gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/encoding/encoding.go (about)

     1  package encoding
     2  
     3  import (
     4  	"reflect"
     5  	"time"
     6  )
     7  
     8  var (
     9  	// type constants
    10  	stringType = reflect.TypeOf("")
    11  	timeType   = reflect.TypeOf(new(time.Time)).Elem()
    12  
    13  	marshalerType   = reflect.TypeOf(new(Marshaler)).Elem()
    14  	unmarshalerType = reflect.TypeOf(new(Unmarshaler)).Elem()
    15  
    16  	emptyInterfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
    17  	mapInterfaceType   = reflect.TypeOf((map[string]interface{})(nil))
    18  )
    19  
    20  // Marshaler is the interface implemented by objects that
    21  // can marshal themselves into a valid RQL pseudo-type.
    22  type Marshaler interface {
    23  	MarshalRQL() (interface{}, error)
    24  }
    25  
    26  // Unmarshaler is the interface implemented by objects
    27  // that can unmarshal a pseudo-type object of themselves.
    28  type Unmarshaler interface {
    29  	UnmarshalRQL(interface{}) error
    30  }
    31  
    32  func init() {
    33  	encoderCache.m = make(map[reflect.Type]encoderFunc)
    34  	decoderCache.m = make(map[decoderCacheKey]decoderFunc)
    35  }
    36  
    37  // IgnoreType causes the encoder to ignore a type when encoding
    38  func IgnoreType(t reflect.Type) {
    39  	encoderCache.Lock()
    40  	encoderCache.m[t] = doNothingEncoder
    41  	encoderCache.Unlock()
    42  }
    43  
    44  func SetTypeEncoding(
    45  	t reflect.Type,
    46  	encode func(value interface{}) (interface{}, error),
    47  	decode func(encoded interface{}, value reflect.Value) error,
    48  ) {
    49  	encoderCache.Lock()
    50  	encoderCache.m[t] = func(v reflect.Value) (interface{}, error) {
    51  		return encode(v.Interface())
    52  	}
    53  	encoderCache.Unlock()
    54  
    55  	dec := func(dv reflect.Value, sv reflect.Value) error {
    56  		return decode(sv.Interface(), dv)
    57  	}
    58  	decoderCache.Lock()
    59  	// decode as pointer
    60  	decoderCache.m[decoderCacheKey{dt: t, st: emptyInterfaceType}] = dec
    61  	// decode as value
    62  	decoderCache.m[decoderCacheKey{dt: t, st: mapInterfaceType}] = dec
    63  
    64  	if t.Kind() == reflect.Ptr {
    65  		decoderCache.m[decoderCacheKey{dt: t.Elem(), st: emptyInterfaceType}] = dec
    66  		decoderCache.m[decoderCacheKey{dt: t.Elem(), st: mapInterfaceType}] = dec
    67  	}
    68  	decoderCache.Unlock()
    69  }