|
27 | 27 | //
|
28 | 28 | // Registry and RegistryBuilder
|
29 | 29 | //
|
30 |
| -// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. For looking up |
31 |
| -// ValueEncoders and Decoders the Registry first attempts to find a ValueEncoder or ValueDecoder for |
32 |
| -// the type provided; if one cannot be found it then checks to see if a registered ValueEncoder or |
33 |
| -// ValueDecoder exists for an interface the type implements. Finally, the reflect.Kind of the type |
34 |
| -// is used to lookup a default ValueEncoder or ValueDecoder for that kind. If no ValueEncoder or |
35 |
| -// ValueDecoder can be found, an error is returned. |
36 |
| -// |
37 |
| -// The Registry also holds a type map. This allows users to retrieve the Go type that should be used |
38 |
| -// when decoding a BSON value into an empty interface. This is primarily only used for the empty |
39 |
| -// interface ValueDecoder. |
40 |
| -// |
41 |
| -// A RegistryBuilder is used to construct a Registry. The Register methods are used to associate |
42 |
| -// either a reflect.Type or a reflect.Kind with a ValueEncoder or ValueDecoder. A RegistryBuilder |
43 |
| -// returned from NewRegistryBuilder contains no registered ValueEncoders nor ValueDecoders and |
44 |
| -// contains an empty type map. |
45 |
| -// |
46 |
| -// The RegisterTypeMapEntry method handles associating a BSON type with a Go type. For example, if |
47 |
| -// you want to decode BSON int64 and int32 values into Go int instances, you would do the following: |
48 |
| -// |
49 |
| -// var regbuilder *RegistryBuilder = ... intType := reflect.TypeOf(int(0)) |
50 |
| -// regbuilder.RegisterTypeMapEntry(bsontype.Int64, intType).RegisterTypeMapEntry(bsontype.Int32, |
51 |
| -// intType) |
| 30 | +// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. See the Registry type |
| 31 | +// documentation for examples of registering various custom encoders and decoders. A Registry can be constructed using a |
| 32 | +// RegistryBuilder, which handles three main types of codecs: |
| 33 | +// |
| 34 | +// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and RegisterTypeDecoder methods. |
| 35 | +// The registered codec will be invoked when encoding/decoding a value whose type matches the registered type exactly. |
| 36 | +// If the registered type is an interface, the codec will be invoked when encoding or decoding values whose type is the |
| 37 | +// interface, but not for values with concrete types that implement the interface. |
| 38 | +// |
| 39 | +// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and RegisterHookDecoder methods. |
| 40 | +// These methods only accept interface types and the registered codecs will be invoked when encoding or decoding values |
| 41 | +// whose types implement the interface. An example of a hook defined by the driver is bson.Marshaler. The driver will |
| 42 | +// call the MarshalBSON method for any value whose type implements bson.Marshaler, regardless of the value's concrete |
| 43 | +// type. |
| 44 | +// |
| 45 | +// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type associations are used when |
| 46 | +// decoding into a bson.D/bson.M or a struct field of type interface{}. For example, by default, BSON int32 and int64 |
| 47 | +// values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would |
| 48 | +// change the behavior so these values decode as Go int instances instead: |
| 49 | +// |
| 50 | +// intType := reflect.TypeOf(int(0)) |
| 51 | +// registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType) |
| 52 | +// |
| 53 | +// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder |
| 54 | +// methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the |
| 55 | +// registered reflect.Kind as long as the value's type doesn't match a registered type or hook encoder/decoder first. |
| 56 | +// These methods should be used to change the behavior for all values for a specific kind. |
| 57 | +// |
| 58 | +// Registry Lookup Procedure |
| 59 | +// |
| 60 | +// When looking up an encoder in a Registry, the precedence rules are as follows: |
| 61 | +// |
| 62 | +// 1. A type encoder registered for the exact type of the value. |
| 63 | +// |
| 64 | +// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to the value. If the |
| 65 | +// value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and bsoncodec.ValueMarshaler), the first |
| 66 | +// one registered will be selected. Note that registries constructed using bson.NewRegistryBuilder have driver-defined |
| 67 | +// hooks registered for the bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those |
| 68 | +// will take precedence over any new hooks. |
| 69 | +// |
| 70 | +// 3. A kind encoder registered for the value's kind. |
| 71 | +// |
| 72 | +// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The same precedence |
| 73 | +// rules apply for decoders, with the exception that an error of type ErrNoDecoder will be returned if no decoder is |
| 74 | +// found. |
52 | 75 | //
|
53 | 76 | // DefaultValueEncoders and DefaultValueDecoders
|
54 | 77 | //
|
|
0 commit comments