func (w *MapFieldWriter) setObject( addr []string, value interface{}, schema *Schema) error { // Set the entire object. First decode into a proper structure var v map[string]interface{} if err := mapstructure.Decode(value, &v); err != nil { return fmt.Errorf("%s: %s", strings.Join(addr, "."), err) } // Make space for additional elements in the address addrCopy := make([]string, len(addr), len(addr)+1) copy(addrCopy, addr) // Set each element in turn var err error for k1, v1 := range v { if err = w.set(append(addrCopy, k1), v1); err != nil { break } } if err != nil { for k1, _ := range v { w.set(append(addrCopy, k1), nil) } } return err }
func (w *MapFieldWriter) setPrimitive( addr []string, v interface{}, schema *Schema) error { k := strings.Join(addr, ".") if v == nil { delete(w.result, k) return nil } var set string switch schema.Type { case TypeBool: var b bool if err := mapstructure.Decode(v, &b); err != nil { return fmt.Errorf("%s: %s", k, err) } set = strconv.FormatBool(b) case TypeString: if err := mapstructure.Decode(v, &set); err != nil { return fmt.Errorf("%s: %s", k, err) } case TypeInt: var n int if err := mapstructure.Decode(v, &n); err != nil { return fmt.Errorf("%s: %s", k, err) } set = strconv.FormatInt(int64(n), 10) case TypeFloat: var n float64 if err := mapstructure.Decode(v, &n); err != nil { return fmt.Errorf("%s: %s", k, err) } set = strconv.FormatFloat(float64(n), 'G', -1, 64) default: return fmt.Errorf("Unknown type: %#v", schema.Type) } w.result[k] = set return nil }
func (w *MapFieldWriter) setList( addr []string, v interface{}, schema *Schema) error { k := strings.Join(addr, ".") setElement := func(idx string, value interface{}) error { addrCopy := make([]string, len(addr), len(addr)+1) copy(addrCopy, addr) return w.set(append(addrCopy, idx), value) } var vs []interface{} if err := mapstructure.Decode(v, &vs); err != nil { return fmt.Errorf("%s: %s", k, err) } // Set the entire list. var err error for i, elem := range vs { is := strconv.FormatInt(int64(i), 10) err = setElement(is, elem) if err != nil { break } } if err != nil { for i, _ := range vs { is := strconv.FormatInt(int64(i), 10) setElement(is, nil) } return err } w.result[k+".#"] = strconv.FormatInt(int64(len(vs)), 10) return nil }