cond_addr_codec.go raw

   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