jeudi 26 novembre 2015

How to convert slice of map to slice of struct in go?

I am trying to convert to map to struct, I am almost done, finally I got a problem, I can not convert slice to struct:

func readDocTo(in bson.M, out reflect.Value) {
    outt := out.Type()
    outk := outt.Kind()

    for {
        if outk == reflect.Ptr && out.IsNil() {
            out.Set(reflect.New(outt.Elem()))
        }
        if outk == reflect.Ptr {
            out = out.Elem()
            outt = out.Type()
            outk = out.Kind()
            continue
        }
        break
    }

    st := out.Type()
    n := st.NumField()
    for i := 0; i < n; i++ {
        field := st.Field(i)
        if field.PkgPath != "" {
            continue // Private field
        }
        tag := field.Tag.Get("bson")
        if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
            tag = string(field.Tag)
        }
        if tag == "-" {
            continue
        }

        // XXX Drop this after a few releases.
        if s := strings.Index(tag, "/"); s >= 0 {
            recommend := tag[:s]
            for _, c := range tag[s+1:] {
                switch c {
                case 'c':
                    recommend += ",omitempty"
                case 's':
                    recommend += ",minsize"
                default:
                    msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", string([]byte{uint8(c)}), tag, st)
                    panic(externalPanic(msg))
                }
            }
            msg := fmt.Sprintf("Replace tag %q in field %s of type %s by %q", tag, field.Name, st, recommend)
            panic(externalPanic(msg))
        }

        if tag == "" {
            tag = strings.ToLower(field.Name)
        }

        fieldt := field.Type
        val, ok := in[tag]
        switch fieldt.Kind() {
        case reflect.Ptr:
            if !ok {
                out.Field(i).Set(reflect.New(fieldt.Elem()))
            } else {
                readDocTo(val.(bson.M), out.Field(i))
            }
        case reflect.String:
            if ok {
                out.Field(i).Set(reflect.ValueOf(val))
            }
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
            out.Field(i).SetInt(reflect.ValueOf(val).Int())
        case reflect.Slice:
            if ok {
                s := reflect.ValueOf(val)
                for j := 0; j < s.Len(); j++ {
                    item := s.Index(j)
                    fmt.Println(item.Interface().(bson.M))
                    fmt.Println(out.Field(i))
                    // TODO
                    // readDocTo(item.Interface().(bson.M), out.Field(i).Elem())
                }
            }
        }

    }
}





Aucun commentaire:

Enregistrer un commentaire