in marshal.go [2407:2490]
func marshalUDT(info TypeInfo, value interface{}) ([]byte, error) {
udt := info.(UDTTypeInfo)
switch v := value.(type) {
case Marshaler:
return v.MarshalCQL(info)
case unsetColumn:
return nil, unmarshalErrorf("invalid request: UnsetValue is unsupported for user defined types")
case UDTMarshaler:
var buf []byte
for _, e := range udt.Elements {
data, err := v.MarshalUDT(e.Name, e.Type)
if err != nil {
return nil, err
}
buf = appendBytes(buf, data)
}
return buf, nil
case map[string]interface{}:
var buf []byte
for _, e := range udt.Elements {
val, ok := v[e.Name]
var data []byte
if ok {
var err error
data, err = Marshal(e.Type, val)
if err != nil {
return nil, err
}
}
buf = appendBytes(buf, data)
}
return buf, nil
}
k := reflect.ValueOf(value)
if k.Kind() == reflect.Ptr {
if k.IsNil() {
return nil, marshalErrorf("cannot marshal %T into %s", value, info)
}
k = k.Elem()
}
if k.Kind() != reflect.Struct || !k.IsValid() {
return nil, marshalErrorf("cannot marshal %T into %s. Accepted types: Marshaler, UDTMarshaler, map[string]interface{}, struct, UnsetValue.", value, info)
}
fields := make(map[string]reflect.Value)
t := reflect.TypeOf(value)
for i := 0; i < t.NumField(); i++ {
sf := t.Field(i)
if tag := sf.Tag.Get("cql"); tag != "" {
fields[tag] = k.Field(i)
}
}
var buf []byte
for _, e := range udt.Elements {
f, ok := fields[e.Name]
if !ok {
f = k.FieldByName(e.Name)
}
var data []byte
if f.IsValid() && f.CanInterface() {
var err error
data, err = Marshal(e.Type, f.Interface())
if err != nil {
return nil, err
}
}
buf = appendBytes(buf, data)
}
return buf, nil
}