hopp/tape/dynamic.go

48 lines
1.4 KiB
Go

package tape
import "fmt"
import "reflect"
// EncodeAny encodes an "any" value. Returns an error if the underlying type is
// unsupported. Supported types are:
//
// - int
// - int<N>
// - uint
// - uint<N>
// - string
// - []<supported type>
// - map[uint16]<supported type>
func EncodeAny(encoder *Encoder, value any) (Tag, error) {
// TODO
}
// TagAny returns the correct tag for an "any" value. Returns an error if the
// underlying type is unsupported. See [EncodeAny] for a list of supported
// types.
func TagAny(value any) (Tag, error) {
// primitives
switch value := value.(type) {
case int, uint: return LI.WithCN(3), nil
case int8, uint8: return LI.WithCN(0), nil
case int16, uint16: return LI.WithCN(1), nil
case int32, uint32: return LI.WithCN(3), nil
case int64, uint64: return LI.WithCN(8), nil
case string: return bufferLenTag(len(value)), nil
case []byte: return bufferLenTag(len(value)), nil
}
// aggregates
reflectType := reflect.TypeOf(value)
switch reflectType.Kind() {
case reflect.Slice: return OTA.WithCN(reflect.ValueOf(value).Len()), nil
case reflect.Array: return OTA.WithCN(reflectType.Len()), nil
case reflect.Map:
if reflectType.Key() == reflect.TypeOf(uint16(0)) {
return OTA.WithCN(reflect.ValueOf(value).Len()), nil
}
return 0, fmt.Errorf("cannot encode map key %T, key must be uint16", value)
}
return 0, fmt.Errorf("cannot encode type %T", value)
}