in marshal.go [2177:2266]
func marshalTuple(info TypeInfo, value interface{}) ([]byte, error) {
tuple := info.(TupleTypeInfo)
switch v := value.(type) {
case unsetColumn:
return nil, unmarshalErrorf("Invalid request: UnsetValue is unsupported for tuples")
case []interface{}:
if len(v) != len(tuple.Elems) {
return nil, unmarshalErrorf("cannont marshal tuple: wrong number of elements")
}
var buf []byte
for i, elem := range v {
if elem == nil {
buf = appendInt(buf, int32(-1))
continue
}
data, err := Marshal(tuple.Elems[i], elem)
if err != nil {
return nil, err
}
n := len(data)
buf = appendInt(buf, int32(n))
buf = append(buf, data...)
}
return buf, nil
}
rv := reflect.ValueOf(value)
t := rv.Type()
k := t.Kind()
switch k {
case reflect.Struct:
if v := t.NumField(); v != len(tuple.Elems) {
return nil, marshalErrorf("can not marshal tuple into struct %v, not enough fields have %d need %d", t, v, len(tuple.Elems))
}
var buf []byte
for i, elem := range tuple.Elems {
field := rv.Field(i)
if field.Kind() == reflect.Ptr && field.IsNil() {
buf = appendInt(buf, int32(-1))
continue
}
data, err := Marshal(elem, field.Interface())
if err != nil {
return nil, err
}
n := len(data)
buf = appendInt(buf, int32(n))
buf = append(buf, data...)
}
return buf, nil
case reflect.Slice, reflect.Array:
size := rv.Len()
if size != len(tuple.Elems) {
return nil, marshalErrorf("can not marshal tuple into %v of length %d need %d elements", k, size, len(tuple.Elems))
}
var buf []byte
for i, elem := range tuple.Elems {
item := rv.Index(i)
if item.Kind() == reflect.Ptr && item.IsNil() {
buf = appendInt(buf, int32(-1))
continue
}
data, err := Marshal(elem, item.Interface())
if err != nil {
return nil, err
}
n := len(data)
buf = appendInt(buf, int32(n))
buf = append(buf, data...)
}
return buf, nil
}
return nil, marshalErrorf("cannot marshal %T into %s. Accepted types: struct, []interface{}, array, slice, UnsetValue.", value, tuple)
}