Don Newton | 379ae25 | 2019-04-01 12:17:06 -0400 | [diff] [blame^] | 1 | // Copyright (C) MongoDB, Inc. 2017-present. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | // not use this file except in compliance with the License. You may obtain |
| 5 | // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | |
| 7 | package bsoncodec |
| 8 | |
| 9 | import ( |
| 10 | "fmt" |
| 11 | "reflect" |
| 12 | "strings" |
| 13 | |
| 14 | "github.com/mongodb/mongo-go-driver/bson/bsonrw" |
| 15 | "github.com/mongodb/mongo-go-driver/bson/bsontype" |
| 16 | ) |
| 17 | |
| 18 | // Marshaler is an interface implemented by types that can marshal themselves |
| 19 | // into a BSON document represented as bytes. The bytes returned must be a valid |
| 20 | // BSON document if the error is nil. |
| 21 | type Marshaler interface { |
| 22 | MarshalBSON() ([]byte, error) |
| 23 | } |
| 24 | |
| 25 | // ValueMarshaler is an interface implemented by types that can marshal |
| 26 | // themselves into a BSON value as bytes. The type must be the valid type for |
| 27 | // the bytes returned. The bytes and byte type together must be valid if the |
| 28 | // error is nil. |
| 29 | type ValueMarshaler interface { |
| 30 | MarshalBSONValue() (bsontype.Type, []byte, error) |
| 31 | } |
| 32 | |
| 33 | // Unmarshaler is an interface implemented by types that can unmarshal a BSON |
| 34 | // document representation of themselves. The BSON bytes can be assumed to be |
| 35 | // valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data |
| 36 | // after returning. |
| 37 | type Unmarshaler interface { |
| 38 | UnmarshalBSON([]byte) error |
| 39 | } |
| 40 | |
| 41 | // ValueUnmarshaler is an interface implemented by types that can unmarshal a |
| 42 | // BSON value representaiton of themselves. The BSON bytes and type can be |
| 43 | // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it |
| 44 | // wishes to retain the data after returning. |
| 45 | type ValueUnmarshaler interface { |
| 46 | UnmarshalBSONValue(bsontype.Type, []byte) error |
| 47 | } |
| 48 | |
| 49 | // ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be |
| 50 | // encoded by the ValueEncoder. |
| 51 | type ValueEncoderError struct { |
| 52 | Name string |
| 53 | Types []reflect.Type |
| 54 | Kinds []reflect.Kind |
| 55 | Received reflect.Value |
| 56 | } |
| 57 | |
| 58 | func (vee ValueEncoderError) Error() string { |
| 59 | typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds)) |
| 60 | for _, t := range vee.Types { |
| 61 | typeKinds = append(typeKinds, t.String()) |
| 62 | } |
| 63 | for _, k := range vee.Kinds { |
| 64 | if k == reflect.Map { |
| 65 | typeKinds = append(typeKinds, "map[string]*") |
| 66 | continue |
| 67 | } |
| 68 | typeKinds = append(typeKinds, k.String()) |
| 69 | } |
| 70 | received := vee.Received.Kind().String() |
| 71 | if vee.Received.IsValid() { |
| 72 | received = vee.Received.Type().String() |
| 73 | } |
| 74 | return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received) |
| 75 | } |
| 76 | |
| 77 | // ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be |
| 78 | // decoded by the ValueDecoder. |
| 79 | type ValueDecoderError struct { |
| 80 | Name string |
| 81 | Types []reflect.Type |
| 82 | Kinds []reflect.Kind |
| 83 | Received reflect.Value |
| 84 | } |
| 85 | |
| 86 | func (vde ValueDecoderError) Error() string { |
| 87 | typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds)) |
| 88 | for _, t := range vde.Types { |
| 89 | typeKinds = append(typeKinds, t.String()) |
| 90 | } |
| 91 | for _, k := range vde.Kinds { |
| 92 | if k == reflect.Map { |
| 93 | typeKinds = append(typeKinds, "map[string]*") |
| 94 | continue |
| 95 | } |
| 96 | typeKinds = append(typeKinds, k.String()) |
| 97 | } |
| 98 | received := vde.Received.Kind().String() |
| 99 | if vde.Received.IsValid() { |
| 100 | received = vde.Received.Type().String() |
| 101 | } |
| 102 | return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received) |
| 103 | } |
| 104 | |
| 105 | // EncodeContext is the contextual information required for a Codec to encode a |
| 106 | // value. |
| 107 | type EncodeContext struct { |
| 108 | *Registry |
| 109 | MinSize bool |
| 110 | } |
| 111 | |
| 112 | // DecodeContext is the contextual information required for a Codec to decode a |
| 113 | // value. |
| 114 | type DecodeContext struct { |
| 115 | *Registry |
| 116 | Truncate bool |
| 117 | // Ancestor is the type of a containing document. This is mainly used to determine what type |
| 118 | // should be used when decoding an embedded document into an empty interface. For example, if |
| 119 | // Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface |
| 120 | // will be decoded into a bson.M. |
| 121 | Ancestor reflect.Type |
| 122 | } |
| 123 | |
| 124 | // ValueCodec is the interface that groups the methods to encode and decode |
| 125 | // values. |
| 126 | type ValueCodec interface { |
| 127 | ValueEncoder |
| 128 | ValueDecoder |
| 129 | } |
| 130 | |
| 131 | // ValueEncoder is the interface implemented by types that can handle the encoding of a value. |
| 132 | type ValueEncoder interface { |
| 133 | EncodeValue(EncodeContext, bsonrw.ValueWriter, reflect.Value) error |
| 134 | } |
| 135 | |
| 136 | // ValueEncoderFunc is an adapter function that allows a function with the correct signature to be |
| 137 | // used as a ValueEncoder. |
| 138 | type ValueEncoderFunc func(EncodeContext, bsonrw.ValueWriter, reflect.Value) error |
| 139 | |
| 140 | // EncodeValue implements the ValueEncoder interface. |
| 141 | func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 142 | return fn(ec, vw, val) |
| 143 | } |
| 144 | |
| 145 | // ValueDecoder is the interface implemented by types that can handle the decoding of a value. |
| 146 | type ValueDecoder interface { |
| 147 | DecodeValue(DecodeContext, bsonrw.ValueReader, reflect.Value) error |
| 148 | } |
| 149 | |
| 150 | // ValueDecoderFunc is an adapter function that allows a function with the correct signature to be |
| 151 | // used as a ValueDecoder. |
| 152 | type ValueDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) error |
| 153 | |
| 154 | // DecodeValue implements the ValueDecoder interface. |
| 155 | func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { |
| 156 | return fn(dc, vr, val) |
| 157 | } |
| 158 | |
| 159 | // CodecZeroer is the interface implemented by Codecs that can also determine if |
| 160 | // a value of the type that would be encoded is zero. |
| 161 | type CodecZeroer interface { |
| 162 | IsTypeZero(interface{}) bool |
| 163 | } |