48 lines
1.4 KiB
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)
|
|
}
|