File: encoding.go

package info (click to toggle)
golang-gopkg-rethinkdb-rethinkdb-go.v6 6.2.1-5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,736 kB
  • sloc: python: 1,382; makefile: 16; sh: 9
file content (69 lines) | stat: -rw-r--r-- 1,893 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package encoding

import (
	"reflect"
	"time"
)

var (
	// type constants
	stringType = reflect.TypeOf("")
	timeType   = reflect.TypeOf(new(time.Time)).Elem()

	marshalerType   = reflect.TypeOf(new(Marshaler)).Elem()
	unmarshalerType = reflect.TypeOf(new(Unmarshaler)).Elem()

	emptyInterfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
	mapInterfaceType   = reflect.TypeOf((map[string]interface{})(nil))
)

// Marshaler is the interface implemented by objects that
// can marshal themselves into a valid RQL pseudo-type.
type Marshaler interface {
	MarshalRQL() (interface{}, error)
}

// Unmarshaler is the interface implemented by objects
// that can unmarshal a pseudo-type object of themselves.
type Unmarshaler interface {
	UnmarshalRQL(interface{}) error
}

func init() {
	encoderCache.m = make(map[reflect.Type]encoderFunc)
	decoderCache.m = make(map[decoderCacheKey]decoderFunc)
}

// IgnoreType causes the encoder to ignore a type when encoding
func IgnoreType(t reflect.Type) {
	encoderCache.Lock()
	encoderCache.m[t] = doNothingEncoder
	encoderCache.Unlock()
}

func SetTypeEncoding(
	t reflect.Type,
	encode func(value interface{}) (interface{}, error),
	decode func(encoded interface{}, value reflect.Value) error,
) {
	encoderCache.Lock()
	encoderCache.m[t] = func(v reflect.Value) (interface{}, error) {
		return encode(v.Interface())
	}
	encoderCache.Unlock()

	dec := func(dv reflect.Value, sv reflect.Value) error {
		return decode(sv.Interface(), dv)
	}
	decoderCache.Lock()
	// decode as pointer
	decoderCache.m[decoderCacheKey{dt: t, st: emptyInterfaceType}] = dec
	// decode as value
	decoderCache.m[decoderCacheKey{dt: t, st: mapInterfaceType}] = dec

	if t.Kind() == reflect.Ptr {
		decoderCache.m[decoderCacheKey{dt: t.Elem(), st: emptyInterfaceType}] = dec
		decoderCache.m[decoderCacheKey{dt: t.Elem(), st: mapInterfaceType}] = dec
	}
	decoderCache.Unlock()
}