in go/fury/type.go [321:391]
func (r *typeResolver) createSerializer(type_ reflect.Type) (s Serializer, err error) {
kind := type_.Kind()
switch kind {
case reflect.Ptr:
if elemKind := type_.Elem().Kind(); elemKind == reflect.Ptr || elemKind == reflect.Interface {
return nil, fmt.Errorf("pointer to pinter/interface are not supported but got type %s", type_)
}
valueSerializer, err := r.getSerializerByType(type_.Elem())
if err != nil {
return nil, err
}
return &ptrToValueSerializer{valueSerializer}, nil
case reflect.Slice:
elem := type_.Elem()
if isDynamicType(elem) {
return sliceSerializer{}, nil
} else {
elemSerializer, err := r.getSerializerByType(type_.Elem())
if err != nil {
return nil, err
}
return &sliceConcreteValueSerializer{
type_: type_,
elemSerializer: elemSerializer,
referencable: nullable(type_.Elem()),
}, nil
}
case reflect.Array:
elem := type_.Elem()
if isDynamicType(elem) {
return arraySerializer{}, nil
} else {
elemSerializer, err := r.getSerializerByType(type_.Elem())
if err != nil {
return nil, err
}
return &arrayConcreteValueSerializer{
type_: type_,
elemSerializer: elemSerializer,
referencable: nullable(type_.Elem()),
}, nil
}
case reflect.Map:
hasKeySerializer, hasValueSerializer := !isDynamicType(type_.Key()), !isDynamicType(type_.Elem())
if hasKeySerializer || hasValueSerializer {
var keySerializer, valueSerializer Serializer
if hasKeySerializer {
keySerializer, err = r.getSerializerByType(type_.Key())
if err != nil {
return nil, err
}
}
if hasValueSerializer {
valueSerializer, err = r.getSerializerByType(type_.Elem())
if err != nil {
return nil, err
}
}
return &mapConcreteKeyValueSerializer{
type_: type_,
keySerializer: keySerializer,
valueSerializer: valueSerializer,
keyReferencable: nullable(type_.Key()),
valueReferencable: nullable(type_.Elem()),
}, nil
} else {
return mapSerializer{}, nil
}
}
return nil, fmt.Errorf("type %s not supported", type_.String())
}