github.com/koko1123/flow-go-1@v0.29.6/model/encoding/cbor/codec.go (about)

     1  package cbor
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	cbor "github.com/fxamacker/cbor/v2"
     8  
     9  	"github.com/koko1123/flow-go-1/model/encoding"
    10  )
    11  
    12  var _ encoding.Marshaler = (*Marshaler)(nil)
    13  
    14  type Marshaler struct{}
    15  
    16  func NewMarshaler() *Marshaler {
    17  	return &Marshaler{}
    18  }
    19  
    20  // EncMode is the default EncMode to use when creating a new cbor Encoder
    21  var EncMode = func() cbor.EncMode {
    22  	// "For best performance, reuse EncMode and DecMode after creating them." [1]
    23  	// [1] https://github.com/fxamacker/cbor
    24  	options := cbor.CoreDetEncOptions() // CBOR deterministic options
    25  	// default: "2021-07-06 21:20:00 +0000 UTC" <- unwanted
    26  	// option : "2021-07-06 21:20:00.820603 +0000 UTC" <- wanted
    27  	options.Time = cbor.TimeRFC3339Nano // option needed for wanted time format
    28  	encMode, err := options.EncMode()
    29  	if err != nil {
    30  		panic(fmt.Errorf("could not extract encoding mode: %w", err))
    31  	}
    32  	return encMode
    33  }()
    34  
    35  // DecMode is the default DecMode to use when creating a new cbor Decoder
    36  var DecMode, _ = cbor.DecOptions{}.DecMode()
    37  
    38  func (m *Marshaler) Marshal(val interface{}) ([]byte, error) {
    39  	return EncMode.Marshal(val)
    40  }
    41  
    42  func (m *Marshaler) Unmarshal(b []byte, val interface{}) error {
    43  	return cbor.Unmarshal(b, val)
    44  }
    45  
    46  func (m *Marshaler) MustMarshal(val interface{}) []byte {
    47  	b, err := m.Marshal(val)
    48  	if err != nil {
    49  		panic(err)
    50  	}
    51  
    52  	return b
    53  }
    54  
    55  func (m *Marshaler) MustUnmarshal(b []byte, val interface{}) {
    56  	err := m.Unmarshal(b, val)
    57  	if err != nil {
    58  		panic(err)
    59  	}
    60  }
    61  
    62  var _ encoding.Codec = (*Codec)(nil)
    63  
    64  type Option func(*Codec)
    65  
    66  // WithEncMode sets the EncMode to use when creating a new cbor Encoder.
    67  func WithEncMode(encMode cbor.EncMode) Option {
    68  	return func(c *Codec) {
    69  		c.encMode = encMode
    70  	}
    71  }
    72  
    73  // WithDecMode sets the DecMode to use when creating a new cbor Decoder.
    74  func WithDecMode(decMode cbor.DecMode) Option {
    75  	return func(c *Codec) {
    76  		c.decMode = decMode
    77  	}
    78  }
    79  
    80  type Codec struct {
    81  	encMode cbor.EncMode
    82  	decMode cbor.DecMode
    83  }
    84  
    85  // NewCodec returns a new cbor Codec with the provided EncMode and DecMode.
    86  // If either is nil, the default cbor EncMode/DecMode will be used.
    87  func NewCodec(opts ...Option) *Codec {
    88  	c := &Codec{
    89  		encMode: EncMode,
    90  		decMode: DecMode,
    91  	}
    92  
    93  	for _, opt := range opts {
    94  		opt(c)
    95  	}
    96  
    97  	return c
    98  }
    99  
   100  func (c *Codec) NewEncoder(w io.Writer) encoding.Encoder {
   101  	return c.encMode.NewEncoder(w)
   102  }
   103  
   104  func (c *Codec) NewDecoder(r io.Reader) encoding.Decoder {
   105  	return c.decMode.NewDecoder(r)
   106  }