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 "reflect"
11 12 "go.mongodb.org/mongo-driver/bson/bsonrw"
13 )
14 15 // condAddrEncoder is the encoder used when a pointer to the encoding value has an encoder.
16 type condAddrEncoder struct {
17 canAddrEnc ValueEncoder
18 elseEnc ValueEncoder
19 }
20 21 var _ ValueEncoder = (*condAddrEncoder)(nil)
22 23 // newCondAddrEncoder returns an condAddrEncoder.
24 func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder {
25 encoder := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
26 return &encoder
27 }
28 29 // EncodeValue is the ValueEncoderFunc for a value that may be addressable.
30 func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
31 if val.CanAddr() {
32 return cae.canAddrEnc.EncodeValue(ec, vw, val)
33 }
34 if cae.elseEnc != nil {
35 return cae.elseEnc.EncodeValue(ec, vw, val)
36 }
37 return ErrNoEncoder{Type: val.Type()}
38 }
39 40 // condAddrDecoder is the decoder used when a pointer to the value has a decoder.
41 type condAddrDecoder struct {
42 canAddrDec ValueDecoder
43 elseDec ValueDecoder
44 }
45 46 var _ ValueDecoder = (*condAddrDecoder)(nil)
47 48 // newCondAddrDecoder returns an CondAddrDecoder.
49 func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder {
50 decoder := condAddrDecoder{canAddrDec: canAddrDec, elseDec: elseDec}
51 return &decoder
52 }
53 54 // DecodeValue is the ValueDecoderFunc for a value that may be addressable.
55 func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
56 if val.CanAddr() {
57 return cad.canAddrDec.DecodeValue(dc, vr, val)
58 }
59 if cad.elseDec != nil {
60 return cad.elseDec.DecodeValue(dc, vr, val)
61 }
62 return ErrNoDecoder{Type: val.Type()}
63 }
64