func goToJv(v interface{}) C.jv { if v == nil { return C.jv_null() } value := reflect.Indirect(reflect.ValueOf(v)) switch value.Type().Kind() { case reflect.Bool: if value.Bool() { return C.jv_true() } else { return C.jv_false() } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return C.jv_number(C.double(value.Int())) // TODO reflect.Uintptr? case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return C.jv_number(C.double(value.Uint())) case reflect.Float32, reflect.Float64: return C.jv_number(C.double(value.Float())) case reflect.String: return C.jv_string(C.CString(value.String())) case reflect.Array, reflect.Slice: n := value.Len() arr := C.jv_array_sized(C.int(n)) for i := 0; i < n; i++ { item := goToJv(value.Index(i).Interface()) arr = C.jv_array_set(C.jv_copy(arr), C.int(i), item) } return arr case reflect.Map: // TODO assert key is string? object := C.jv_object() for _, k := range value.MapKeys() { key := goToJv(k.Interface()) mapValue := goToJv(value.MapIndex(k).Interface()) object = C.jv_object_set(object, key, mapValue) } return object } msg := fmt.Sprintf("unknown type for: %v", value.Interface()) return C.jv_invalid_with_msg(C.jv_string(C.CString(msg))) }
// ObjectSet will add val to the object under the given key. // // This is the equivalent of `jv[key] = val`. // // Consumes invocant and both key and val func (jv *Jv) ObjectSet(key *Jv, val *Jv) *Jv { return &Jv{C.jv_object_set(jv.jv, key.jv, val.jv)} }