bson

package
v2.0.0-beta2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2024 License: Apache-2.0 Imports: 27 Imported by: 4

Documentation

Overview

Package bson is a library for reading, writing, and manipulating BSON. BSON is a binary serialization format used to store documents and make remote procedure calls in MongoDB. The BSON specification is located at https://bsonspec.org. The BSON library handles marshaling and unmarshaling of values through a configurable codec system. For a description of the codec system and examples of registering custom codecs, see the bsoncodec package. For additional information and usage examples, check out the Work with BSON page in the Go Driver docs site.

Raw BSON

The Raw family of types is used to validate and retrieve elements from a slice of bytes. This type is most useful when you want do lookups on BSON bytes without unmarshaling it into another type.

Example:

var raw bson.Raw = ... // bytes from somewhere
err := raw.Validate()
if err != nil { return err }
val := raw.Lookup("foo")
i32, ok := val.Int32OK()
// do something with i32...

Native Go Types

The D and M types defined in this package can be used to build representations of BSON using native Go types. D is a slice and M is a map. For more information about the use cases for these types, see the documentation on the type definitions.

Note that a D should not be constructed with duplicate key names, as that can cause undefined server behavior.

Example:

bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}

When decoding BSON to a D or M, the following type mappings apply when unmarshaling:

  1. BSON int32 unmarshals to an int32.
  2. BSON int64 unmarshals to an int64.
  3. BSON double unmarshals to a float64.
  4. BSON string unmarshals to a string.
  5. BSON boolean unmarshals to a bool.
  6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M).
  7. BSON array unmarshals to a bson.A.
  8. BSON ObjectId unmarshals to a primitive.ObjectID.
  9. BSON datetime unmarshals to a primitive.DateTime.
  10. BSON binary unmarshals to a primitive.Binary.
  11. BSON regular expression unmarshals to a primitive.Regex.
  12. BSON JavaScript unmarshals to a primitive.JavaScript.
  13. BSON code with scope unmarshals to a primitive.CodeWithScope.
  14. BSON timestamp unmarshals to an primitive.Timestamp.
  15. BSON 128-bit decimal unmarshals to an primitive.Decimal128.
  16. BSON min key unmarshals to an primitive.MinKey.
  17. BSON max key unmarshals to an primitive.MaxKey.
  18. BSON undefined unmarshals to a primitive.Undefined.
  19. BSON null unmarshals to nil.
  20. BSON DBPointer unmarshals to a primitive.DBPointer.
  21. BSON symbol unmarshals to a primitive.Symbol.

The above mappings also apply when marshaling a D or M to BSON. Some other useful marshaling mappings are:

  1. time.Time marshals to a BSON datetime.
  2. int8, int16, and int32 marshal to a BSON int32.
  3. int marshals to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, inclusive, and a BSON int64 otherwise.
  4. int64 marshals to BSON int64 (unless Encoder.IntMinSize is set).
  5. uint8 and uint16 marshal to a BSON int32.
  6. uint, uint32, and uint64 marshal to a BSON int64 (unless Encoder.IntMinSize is set).
  7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshaling a BSON null or undefined value into a string will yield the empty string.).

Structs

Structs can be marshaled/unmarshaled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended JSON, the following rules apply:

  1. Only exported fields in structs will be marshaled or unmarshaled.

  2. When marshaling a struct, each field will be lowercased to generate the key for the corresponding BSON element. For example, a struct field named "Foo" will generate key "foo". This can be overridden via a struct tag (e.g. `bson:"fooField"` to generate key "fooField" instead).

  3. An embedded struct field is marshaled as a subdocument. The key will be the lowercased name of the field's type.

  4. A pointer field is marshaled as the underlying type if the pointer is non-nil. If the pointer is nil, it is marshaled as a BSON null value.

  5. When unmarshaling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents unmarshaled into an interface{} field will be unmarshaled as a D.

The encoding of each struct field can be customized by the "bson" struct tag.

This tag behavior is configurable, and different struct tag behavior can be configured by initializing a new bsoncodec.StructCodec with the desired tag parser and registering that StructCodec onto the Registry. By default, JSON tags are not honored, but that can be enabled by creating a StructCodec with JSONFallbackStructTagParser, like below:

Example:

structcodec, _ := bsoncodec.NewStructCodec(bsoncodec.JSONFallbackStructTagParser)

The bson tag gives the name of the field, possibly followed by a comma-separated list of options. The name may be empty in order to specify options without overriding the default field name. The following options can be used to configure behavior:

  1. omitempty: If the "omitempty" struct tag is specified on a field, the field will not be marshaled if it is set to an "empty" value. Numbers, booleans, and strings are considered empty if their value is equal to the zero value for the type (i.e. 0 for numbers, false for booleans, and "" for strings). Slices, maps, and arrays are considered empty if they are of length zero. Interfaces and pointers are considered empty if their value is nil. By default, structs are only considered empty if the struct type implements [bsoncodec.Zeroer] and the IsZero method returns true. Struct types that do not implement [bsoncodec.Zeroer] are never considered empty and will be marshaled as embedded documents. NOTE: It is recommended that this tag be used for all slice and map fields.

  2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of the field can fit in a signed int32, the field will be serialized as a BSON int32 rather than a BSON int64. For other types, this tag is ignored.

  3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles unmarshaled into that field will be truncated at the decimal point. For example, if 3.14 is unmarshaled into a field of type int, it will be unmarshaled as 3. If this tag is not specified, the decoder will throw an error if the value cannot be decoded without losing precision. For float64 or non-numeric types, this tag is ignored.

  4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when marshaling and "un-flattened" when unmarshaling. This means that all of the fields in that struct/map will be pulled up one level and will become top-level fields rather than being fields in a nested document. For example, if a map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will be {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If there are duplicated fields in the resulting document when an inlined struct is marshaled, the inlined field will be overwritten. If there are duplicated fields in the resulting document when an inlined map is marshaled, an error will be returned. This tag can be used with fields that are pointers to structs. If an inlined pointer field is nil, it will not be marshaled. For fields that are not maps or structs, this tag is ignored.

Marshaling and Unmarshaling

Manually marshaling and unmarshaling can be done with the Marshal and Unmarshal family of functions.

bsoncodec code provides a system for encoding values to BSON representations and decoding values from BSON representations. This package considers both binary BSON and ExtendedJSON as BSON representations. The types in this package enable a flexible system for handling this encoding and decoding.

The codec system is composed of two parts:

1) ValueEncoder and ValueDecoder that handle encoding and decoding Go values to and from BSON representations.

2) A Registry that holds these ValueEncoders and ValueDecoders and provides methods for retrieving them.

Index

Examples

Constants

View Source
const (
	MaxDecimal128Exp = 6111
	MinDecimal128Exp = -6176
)

These constants are the maximum and minimum values for the exponent field in a decimal128 value.

View Source
const (
	TypeBinaryGeneric     byte = 0x00
	TypeBinaryFunction    byte = 0x01
	TypeBinaryBinaryOld   byte = 0x02
	TypeBinaryUUIDOld     byte = 0x03
	TypeBinaryUUID        byte = 0x04
	TypeBinaryMD5         byte = 0x05
	TypeBinaryEncrypted   byte = 0x06
	TypeBinaryColumn      byte = 0x07
	TypeBinarySensitive   byte = 0x08
	TypeBinaryUserDefined byte = 0x80
)

BSON binary element subtypes as described in https://bsonspec.org/spec.html.

Variables

View Source
var (
	ErrParseNaN    = errors.New("cannot parse NaN as a *big.Int")
	ErrParseInf    = errors.New("cannot parse Infinity as a *big.Int")
	ErrParseNegInf = errors.New("cannot parse -Infinity as a *big.Int")
)

These errors are returned when an invalid value is parsed as a big.Int.

View Source
var ErrDecodeToNil = errors.New("cannot Decode to nil value")

ErrDecodeToNil is the error returned when trying to decode to a nil value

View Source
var ErrEOA = errors.New("end of array")

ErrEOA is the error returned when the end of a BSON array has been reached.

View Source
var ErrEOD = errors.New("end of document")

ErrEOD is the error returned when the end of a BSON document has been reached.

View Source
var ErrInvalidHex = errors.New("the provided hex string is not a valid ObjectID")

ErrInvalidHex indicates that a hex string cannot be converted to an ObjectID.

View Source
var ErrInvalidJSON = errors.New("invalid JSON input")

ErrInvalidJSON indicates the JSON input is invalid

View Source
var (
	// ErrMgoSetZero may be returned from a SetBSON method to have the value set to its respective zero value.
	ErrMgoSetZero = errors.New("set to zero")
)
View Source
var ErrNilContext = errors.New("DecodeContext cannot be nil")

ErrNilContext is returned when the provided DecodeContext is nil.

View Source
var ErrNilReader = errors.New("nil reader")

ErrNilReader indicates that an operation was attempted on a nil bson.Reader.

View Source
var ErrNilRegistry = errors.New("Registry cannot be nil")

ErrNilRegistry is returned when the provided registry is nil.

Functions

func IndentExtJSON

func IndentExtJSON(dst *bytes.Buffer, src []byte, prefix, indent string) error

IndentExtJSON will prefix and indent the provided extended JSON src and append it to dst.

func Marshal

func Marshal(val interface{}) ([]byte, error)

Marshal returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed into a document, MarshalValue should be used instead.

Marshal will use the default registry created by NewRegistry to recursively marshal val into a []byte. Marshal will inspect struct tags and alter the marshaling process accordingly.

func MarshalExtJSON

func MarshalExtJSON(val interface{}, canonical, escapeHTML bool) ([]byte, error)

MarshalExtJSON returns the extended JSON encoding of val.

func MarshalExtJSONIndent

func MarshalExtJSONIndent(val interface{}, canonical, escapeHTML bool, prefix, indent string) ([]byte, error)

MarshalExtJSONIndent returns the extended JSON encoding of val with each line with prefixed and indented.

func Unmarshal

func Unmarshal(data []byte, val interface{}) error

Unmarshal parses the BSON-encoded data and stores the result in the value pointed to by val. If val is nil or not a pointer, Unmarshal returns an error.

func UnmarshalExtJSON

func UnmarshalExtJSON(data []byte, canonicalOnly bool, val interface{}) error

UnmarshalExtJSON parses the extended JSON-encoded data and stores the result in the value pointed to by val. If val is nil or not a pointer, UnmarshalExtJSON returns an error.

If canonicalOnly is true, UnmarshalExtJSON returns an error if the Extended JSON was not marshaled in canonical mode.

For more information about Extended JSON, see https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/

func UnmarshalValue

func UnmarshalValue(t Type, data []byte, val interface{}) error

UnmarshalValue parses the BSON value of type t with bson.NewRegistry() and stores the result in the value pointed to by val. If val is nil or not a pointer, UnmarshalValue returns an error.

Types

type A

type A []interface{}

An A is an ordered representation of a BSON array.

Example usage:

bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}

type ArrayReader

type ArrayReader interface {
	ReadValue() (ValueReader, error)
}

ArrayReader is implemented by types that allow reading values from a BSON array.

type ArrayWriter

type ArrayWriter interface {
	WriteArrayElement() (ValueWriter, error)
	WriteArrayEnd() error
}

ArrayWriter is the interface used to create a BSON or BSON adjacent array. Callers must ensure they call WriteArrayEnd when they have finished creating the array.

type Binary

type Binary struct {
	Subtype byte
	Data    []byte
}

Binary represents a BSON binary value.

func (Binary) Equal

func (bp Binary) Equal(bp2 Binary) bool

Equal compares bp to bp2 and returns true if they are equal.

func (Binary) IsZero

func (bp Binary) IsZero() bool

IsZero returns if bp is the empty Binary.

type CodeWithScope

type CodeWithScope struct {
	Code  JavaScript
	Scope interface{}
}

CodeWithScope represents a BSON JavaScript code with scope value.

func (CodeWithScope) String

func (cws CodeWithScope) String() string

type D

type D []E

D is an ordered representation of a BSON document. This type should be used when the order of the elements matters, such as MongoDB command documents. If the order of the elements does not matter, an M should be used instead.

Example usage:

bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}

func (D) MarshalJSON

func (d D) MarshalJSON() ([]byte, error)

MarshalJSON encodes D into JSON.

func (D) String

func (d D) String() string

func (*D) UnmarshalJSON

func (d *D) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes D from JSON.

type DBPointer

type DBPointer struct {
	DB      string
	Pointer ObjectID
}

DBPointer represents a BSON dbpointer value.

func (DBPointer) Equal

func (d DBPointer) Equal(d2 DBPointer) bool

Equal compares d to d2 and returns true if they are equal.

func (DBPointer) IsZero

func (d DBPointer) IsZero() bool

IsZero returns if d is the empty DBPointer.

func (DBPointer) String

func (d DBPointer) String() string

type DateTime

type DateTime int64

DateTime represents the BSON datetime value.

func NewDateTimeFromTime

func NewDateTimeFromTime(t time.Time) DateTime

NewDateTimeFromTime creates a new DateTime from a Time.

func (DateTime) MarshalJSON

func (d DateTime) MarshalJSON() ([]byte, error)

MarshalJSON marshal to time type.

func (DateTime) Time

func (d DateTime) Time() time.Time

Time returns the date as a time type.

func (*DateTime) UnmarshalJSON

func (d *DateTime) UnmarshalJSON(data []byte) error

UnmarshalJSON creates a primitive.DateTime from a JSON string.

type Decimal128

type Decimal128 struct {
	// contains filtered or unexported fields
}

Decimal128 holds decimal128 BSON values.

func NewDecimal128

func NewDecimal128(h, l uint64) Decimal128

NewDecimal128 creates a Decimal128 using the provide high and low uint64s.

func ParseDecimal128

func ParseDecimal128(s string) (Decimal128, error)

ParseDecimal128 takes the given string and attempts to parse it into a valid Decimal128 value.

func ParseDecimal128FromBigInt

func ParseDecimal128FromBigInt(bi *big.Int, exp int) (Decimal128, bool)

ParseDecimal128FromBigInt attempts to parse the given significand and exponent into a valid Decimal128 value.

func (Decimal128) BigInt

func (d Decimal128) BigInt() (*big.Int, int, error)

BigInt returns significand as big.Int and exponent, bi * 10 ^ exp.

func (Decimal128) GetBytes

func (d Decimal128) GetBytes() (uint64, uint64)

GetBytes returns the underlying bytes of the BSON decimal value as two uint64 values. The first contains the most first 8 bytes of the value and the second contains the latter.

func (Decimal128) IsInf

func (d Decimal128) IsInf() int

IsInf returns:

+1 d == Infinity
 0 other case
-1 d == -Infinity

func (Decimal128) IsNaN

func (d Decimal128) IsNaN() bool

IsNaN returns whether d is NaN.

func (Decimal128) IsZero

func (d Decimal128) IsZero() bool

IsZero returns true if d is the empty Decimal128.

func (Decimal128) MarshalJSON

func (d Decimal128) MarshalJSON() ([]byte, error)

MarshalJSON returns Decimal128 as a string.

func (Decimal128) String

func (d Decimal128) String() string

String returns a string representation of the decimal value.

func (*Decimal128) UnmarshalJSON

func (d *Decimal128) UnmarshalJSON(b []byte) error

UnmarshalJSON creates a Decimal128 from a JSON string, an extended JSON $numberDecimal value, or the string "null". If b is a JSON string or extended JSON value, d will have the value of that string, and if b is "null", d will be unchanged.

type DecodeContext

type DecodeContext struct {
	*Registry
	// contains filtered or unexported fields
}

DecodeContext is the contextual information required for a Codec to decode a value.

type DecodeError

type DecodeError struct {
	// contains filtered or unexported fields
}

DecodeError represents an error that occurs when unmarshalling BSON bytes into a native Go type.

func (*DecodeError) Error

func (de *DecodeError) Error() string

Error implements the error interface.

func (*DecodeError) Keys

func (de *DecodeError) Keys() []string

Keys returns the BSON key path that caused an error as a slice of strings. The keys in the slice are in top-down order. For example, if the document being unmarshalled was {a: {b: {c: 1}}} and the value for c was supposed to be a string, the keys slice will be ["a", "b", "c"].

func (*DecodeError) Unwrap

func (de *DecodeError) Unwrap() error

Unwrap returns the underlying error

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

A Decoder reads and decodes BSON documents from a stream. It reads from a ValueReader as the source of BSON data.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Marshal a BSON document that contains the name, SKU, and price (in cents)
	// of a product.
	doc := bson.D{
		{Key: "name", Value: "Cereal Rounds"},
		{Key: "sku", Value: "AB12345"},
		{Key: "price_cents", Value: 399},
	}
	data, err := bson.Marshal(doc)
	if err != nil {
		panic(err)
	}

	// Create a Decoder that reads the marshaled BSON document and use it to
	// unmarshal the document into a Product struct.
	decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(data)))

	type Product struct {
		Name  string `bson:"name"`
		SKU   string `bson:"sku"`
		Price int64  `bson:"price_cents"`
	}

	var res Product
	err = decoder.Decode(&res)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", res)
}
Output:

{Name:Cereal Rounds SKU:AB12345 Price:399}
Example (ExtendedJSON)
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Define an Extended JSON document that contains the name, SKU, and price
	// (in cents) of a product.
	data := []byte(`{"name":"Cereal Rounds","sku":"AB12345","price_cents":{"$numberLong":"399"}}`)

	// Create a Decoder that reads the Extended JSON document and use it to
	// unmarshal the document into a Product struct.
	vr, err := bson.NewExtJSONValueReader(bytes.NewReader(data), true)
	if err != nil {
		panic(err)
	}
	decoder := bson.NewDecoder(vr)

	type Product struct {
		Name  string `bson:"name"`
		SKU   string `bson:"sku"`
		Price int64  `bson:"price_cents"`
	}

	var res Product
	err = decoder.Decode(&res)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", res)
}
Output:

{Name:Cereal Rounds SKU:AB12345 Price:399}
Example (MultipleExtendedJSONDocuments)
package main

import (
	"bytes"
	"errors"
	"fmt"
	"io"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Define a newline-separated sequence of Extended JSON documents that
	// contain X,Y coordinates.
	data := []byte(`
{"x":{"$numberInt":"0"},"y":{"$numberInt":"0"}}
{"x":{"$numberInt":"1"},"y":{"$numberInt":"1"}}
{"x":{"$numberInt":"2"},"y":{"$numberInt":"2"}}
{"x":{"$numberInt":"3"},"y":{"$numberInt":"3"}}
{"x":{"$numberInt":"4"},"y":{"$numberInt":"4"}}
`)

	// Create a Decoder that reads the Extended JSON documents and use it to
	// unmarshal the documents Coordinate structs.
	vr, err := bson.NewExtJSONValueReader(bytes.NewReader(data), true)
	if err != nil {
		panic(err)
	}
	decoder := bson.NewDecoder(vr)

	type Coordinate struct {
		X int
		Y int
	}

	// Read and unmarshal each Extended JSON document from the sequence. If
	// Decode returns error io.EOF, that means the Decoder has reached the end
	// of the input, so break the loop.
	for {
		var res Coordinate
		err = decoder.Decode(&res)
		if errors.Is(err, io.EOF) {
			break
		}
		if err != nil {
			panic(err)
		}

		fmt.Printf("%+v\n", res)
	}
}
Output:

{X:0 Y:0}
{X:1 Y:1}
{X:2 Y:2}
{X:3 Y:3}
{X:4 Y:4}

func NewDecoder

func NewDecoder(vr ValueReader) *Decoder

NewDecoder returns a new decoder that reads from vr.

func (*Decoder) AllowTruncatingDoubles

func (d *Decoder) AllowTruncatingDoubles()

AllowTruncatingDoubles causes the Decoder to truncate the fractional part of BSON "double" values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, or int64) struct field. The truncation logic does not apply to BSON "decimal128" values.

func (*Decoder) BinaryAsSlice

func (d *Decoder) BinaryAsSlice()

BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.

func (*Decoder) Decode

func (d *Decoder) Decode(val interface{}) error

Decode reads the next BSON document from the stream and decodes it into the value pointed to by val.

See Unmarshal for details about BSON unmarshaling behavior.

func (*Decoder) DefaultDocumentM

func (d *Decoder) DefaultDocumentM()

DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This behavior is restricted to data typed as "interface{}" or "map[string]interface{}".

Example
package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Marshal a BSON document that contains a city name and a nested document
	// with various city properties.
	doc := bson.D{
		{Key: "name", Value: "New York"},
		{Key: "properties", Value: bson.D{
			{Key: "state", Value: "NY"},
			{Key: "population", Value: 8_804_190},
			{Key: "elevation", Value: 10},
		}},
	}
	data, err := bson.Marshal(doc)
	if err != nil {
		panic(err)
	}

	// Create a Decoder that reads the marshaled BSON document and use it to unmarshal the document
	// into a City struct.
	decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(data)))

	type City struct {
		Name       string      `bson:"name"`
		Properties interface{} `bson:"properties"`
	}

	// Configure the Decoder to default to decoding BSON documents as the M
	// type if the decode destination has no type information. The Properties
	// field in the City struct will be decoded as a "M" (i.e. map) instead
	// of the default "D".
	decoder.DefaultDocumentM()

	var res City
	err = decoder.Decode(&res)
	if err != nil {
		panic(err)
	}

	data, err = json.Marshal(res)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", string(data))
}
Output:

{"Name":"New York","Properties":{"elevation":10,"population":8804190,"state":"NY"}}

func (*Decoder) ObjectIDAsHexString

func (d *Decoder) ObjectIDAsHexString()

ObjectIDAsHexString causes the Decoder to decode object IDs to their hex representation.

func (*Decoder) Reset

func (d *Decoder) Reset(vr ValueReader)

Reset will reset the state of the decoder, using the same *DecodeContext used in the original construction but using vr for reading.

func (*Decoder) SetRegistry

func (d *Decoder) SetRegistry(r *Registry)

SetRegistry replaces the current registry of the decoder with r.

func (*Decoder) UseJSONStructTags

func (d *Decoder) UseJSONStructTags()

UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson" struct tag is not specified.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Marshal a BSON document that contains the name, SKU, and price (in cents)
	// of a product.
	doc := bson.D{
		{Key: "name", Value: "Cereal Rounds"},
		{Key: "sku", Value: "AB12345"},
		{Key: "price_cents", Value: 399},
	}
	data, err := bson.Marshal(doc)
	if err != nil {
		panic(err)
	}

	// Create a Decoder that reads the marshaled BSON document and use it to
	// unmarshal the document into a Product struct.
	decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(data)))

	type Product struct {
		Name  string `json:"name"`
		SKU   string `json:"sku"`
		Price int64  `json:"price_cents"`
	}

	// Configure the Decoder to use "json" struct tags when decoding if "bson"
	// struct tags are not present.
	decoder.UseJSONStructTags()

	var res Product
	err = decoder.Decode(&res)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", res)
}
Output:

{Name:Cereal Rounds SKU:AB12345 Price:399}

func (*Decoder) UseLocalTimeZone

func (d *Decoder) UseLocalTimeZone()

UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead of the UTC timezone.

func (*Decoder) ZeroMaps

func (d *Decoder) ZeroMaps()

ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value passed to Decode before unmarshaling BSON documents into them.

func (*Decoder) ZeroStructs

func (d *Decoder) ZeroStructs()

ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination value passed to Decode before unmarshaling BSON documents into them.

type DocumentReader

type DocumentReader interface {
	ReadElement() (string, ValueReader, error)
}

DocumentReader is implemented by types that allow reading elements from a BSON document.

type DocumentWriter

type DocumentWriter interface {
	WriteDocumentElement(string) (ValueWriter, error)
	WriteDocumentEnd() error
}

DocumentWriter is the interface used to create a BSON or BSON adjacent document. Callers must ensure they call WriteDocumentEnd when they have finished creating the document.

type E

type E struct {
	Key   string
	Value interface{}
}

E represents a BSON element for a D. It is usually used inside a D.

type EncodeContext

type EncodeContext struct {
	*Registry
	// contains filtered or unexported fields
}

EncodeContext is the contextual information required for a Codec to encode a value.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

An Encoder writes a serialization format to an output stream. It writes to a ValueWriter as the destination of BSON data.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an Encoder that writes BSON values to a bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	encoder := bson.NewEncoder(vw)

	type Product struct {
		Name  string `bson:"name"`
		SKU   string `bson:"sku"`
		Price int64  `bson:"price_cents"`
	}

	// Use the Encoder to marshal a BSON document that contains the name, SKU,
	// and price (in cents) of a product.
	product := Product{
		Name:  "Cereal Rounds",
		SKU:   "AB12345",
		Price: 399,
	}
	err := encoder.Encode(product)
	if err != nil {
		panic(err)
	}

	// Print the BSON document as Extended JSON by converting it to bson.Raw.
	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"name": "Cereal Rounds","sku": "AB12345","price_cents": {"$numberLong":"399"}}
Example (ExtendedJSON)
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an Encoder that writes canonical Extended JSON values to a
	// bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewExtJSONValueWriter(buf, true, false)
	encoder := bson.NewEncoder(vw)

	type Product struct {
		Name  string `bson:"name"`
		SKU   string `bson:"sku"`
		Price int64  `bson:"price_cents"`
	}

	// Use the Encoder to marshal a BSON document that contains the name, SKU,
	// and price (in cents) of a product.
	product := Product{
		Name:  "Cereal Rounds",
		SKU:   "AB12345",
		Price: 399,
	}
	err := encoder.Encode(product)
	if err != nil {
		panic(err)
	}

	fmt.Println(buf.String())
}
Output:

{"name":"Cereal Rounds","sku":"AB12345","price_cents":{"$numberLong":"399"}}
Example (MultipleBSONDocuments)
package main

import (
	"bytes"
	"errors"
	"fmt"
	"io"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an Encoder that writes BSON values to a bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	encoder := bson.NewEncoder(vw)

	type Coordinate struct {
		X int
		Y int
	}

	// Use the encoder to marshal 5 Coordinate values as a sequence of BSON
	// documents.
	for i := 0; i < 5; i++ {
		err := encoder.Encode(Coordinate{
			X: i,
			Y: i + 1,
		})
		if err != nil {
			panic(err)
		}
	}

	// Read each marshaled BSON document from the buffer and print them as
	// Extended JSON by converting them to bson.Raw.
	for {
		doc, err := bson.ReadDocument(buf)
		if errors.Is(err, io.EOF) {
			return
		}
		if err != nil {
			panic(err)
		}
		fmt.Println(doc.String())
	}
}
Output:

{"x": {"$numberInt":"0"},"y": {"$numberInt":"1"}}
{"x": {"$numberInt":"1"},"y": {"$numberInt":"2"}}
{"x": {"$numberInt":"2"},"y": {"$numberInt":"3"}}
{"x": {"$numberInt":"3"},"y": {"$numberInt":"4"}}
{"x": {"$numberInt":"4"},"y": {"$numberInt":"5"}}
Example (MultipleExtendedJSONDocuments)
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an Encoder that writes canonical Extended JSON values to a
	// bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewExtJSONValueWriter(buf, true, false)
	encoder := bson.NewEncoder(vw)

	type Coordinate struct {
		X int
		Y int
	}

	// Use the encoder to marshal 5 Coordinate values as a sequence of Extended
	// JSON documents.
	for i := 0; i < 5; i++ {
		err := encoder.Encode(Coordinate{
			X: i,
			Y: i + 1,
		})
		if err != nil {
			panic(err)
		}
	}

	fmt.Println(buf.String())
}
Output:

{"x":{"$numberInt":"0"},"y":{"$numberInt":"1"}}
{"x":{"$numberInt":"1"},"y":{"$numberInt":"2"}}
{"x":{"$numberInt":"2"},"y":{"$numberInt":"3"}}
{"x":{"$numberInt":"3"},"y":{"$numberInt":"4"}}
{"x":{"$numberInt":"4"},"y":{"$numberInt":"5"}}

func NewEncoder

func NewEncoder(vw ValueWriter) *Encoder

NewEncoder returns a new encoder that writes to vw.

func (*Encoder) Encode

func (e *Encoder) Encode(val interface{}) error

Encode writes the BSON encoding of val to the stream.

See Marshal for details about BSON marshaling behavior.

func (*Encoder) ErrorOnInlineDuplicates

func (e *Encoder) ErrorOnInlineDuplicates()

ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in the marshaled BSON when the "inline" struct tag option is set.

func (*Encoder) IntMinSize

func (e *Encoder) IntMinSize()

IntMinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) that can represent the integer value.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an encoder that will marshal integers as the minimum BSON int size
	// (either 32 or 64 bits) that can represent the integer value.
	type foo struct {
		Bar uint32
	}

	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)

	enc := bson.NewEncoder(vw)
	enc.IntMinSize()

	err := enc.Encode(foo{2})
	if err != nil {
		panic(err)
	}

	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"bar": {"$numberInt":"2"}}

func (*Encoder) NilByteSliceAsEmpty

func (e *Encoder) NilByteSliceAsEmpty()

NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values instead of BSON null.

func (*Encoder) NilMapAsEmpty

func (e *Encoder) NilMapAsEmpty()

NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON null.

func (*Encoder) NilSliceAsEmpty

func (e *Encoder) NilSliceAsEmpty()

NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON null.

func (*Encoder) OmitZeroStruct

func (e *Encoder) OmitZeroStruct()

OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{}) as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.

Note that the Encoder only examines exported struct fields when determining if a struct is the zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.

func (*Encoder) Reset

func (e *Encoder) Reset(vw ValueWriter)

Reset will reset the state of the Encoder, using the same *EncodeContext used in the original construction but using vw.

func (*Encoder) SetRegistry

func (e *Encoder) SetRegistry(r *Registry)

SetRegistry replaces the current registry of the Encoder with r.

func (*Encoder) StringifyMapKeysWithFmt

func (e *Encoder) StringifyMapKeysWithFmt()

StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name strings using fmt.Sprint instead of the default string conversion logic.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

type CityState struct {
	City  string
	State string
}

func (k CityState) String() string {
	return fmt.Sprintf("%s, %s", k.City, k.State)
}

func main() {
	// Create an Encoder that writes BSON values to a bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	encoder := bson.NewEncoder(vw)

	// Configure the Encoder to convert Go map keys to BSON document field names
	// using fmt.Sprintf instead of the default string conversion logic.
	encoder.StringifyMapKeysWithFmt()

	// Use the Encoder to marshal a BSON document that contains is a map of
	// city and state to a list of zip codes in that city.
	zipCodes := map[CityState][]int{
		{City: "New York", State: "NY"}: {10001, 10301, 10451},
	}
	err := encoder.Encode(zipCodes)
	if err != nil {
		panic(err)
	}

	// Print the BSON document as Extended JSON by converting it to bson.Raw.
	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"New York, NY": [{"$numberInt":"10001"},{"$numberInt":"10301"},{"$numberInt":"10451"}]}

func (*Encoder) UseJSONStructTags

func (e *Encoder) UseJSONStructTags()

UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson" struct tag is not specified.

Example
package main

import (
	"bytes"
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create an Encoder that writes BSON values to a bytes.Buffer.
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	encoder := bson.NewEncoder(vw)

	type Product struct {
		Name  string `json:"name"`
		SKU   string `json:"sku"`
		Price int64  `json:"price_cents"`
	}

	// Configure the Encoder to use "json" struct tags when decoding if "bson"
	// struct tags are not present.
	encoder.UseJSONStructTags()

	// Use the Encoder to marshal a BSON document that contains the name, SKU,
	// and price (in cents) of a product.
	product := Product{
		Name:  "Cereal Rounds",
		SKU:   "AB12345",
		Price: 399,
	}
	err := encoder.Encode(product)
	if err != nil {
		panic(err)
	}

	// Print the BSON document as Extended JSON by converting it to bson.Raw.
	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"name": "Cereal Rounds","sku": "AB12345","price_cents": {"$numberLong":"399"}}

type JavaScript

type JavaScript string

JavaScript represents a BSON JavaScript code value.

type KeyMarshaler

type KeyMarshaler interface {
	MarshalKey() (key string, err error)
}

KeyMarshaler is the interface implemented by an object that can marshal itself into a string key. This applies to types used as map keys and is similar to encoding.TextMarshaler.

type KeyUnmarshaler

type KeyUnmarshaler interface {
	UnmarshalKey(key string) error
}

KeyUnmarshaler is the interface implemented by an object that can unmarshal a string representation of itself. This applies to types used as map keys and is similar to encoding.TextUnmarshaler.

UnmarshalKey must be able to decode the form generated by MarshalKey. UnmarshalKey must copy the text if it wishes to retain the text after returning.

type M

type M map[string]interface{}

M is an unordered representation of a BSON document. This type should be used when the order of the elements does not matter. This type is handled as a regular map[string]interface{} when encoding and decoding. Elements will be serialized in an undefined, random order. If the order of the elements matters, a D should be used instead.

Example usage:

bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}

func (M) String

func (m M) String() string

type Marshaler

type Marshaler interface {
	MarshalBSON() ([]byte, error)
}

Marshaler is the interface implemented by types that can marshal themselves into a valid BSON document.

Implementations of Marshaler must return a full BSON document. To create custom BSON marshaling behavior for individual values in a BSON document, implement the ValueMarshaler interface instead.

type MaxKey

type MaxKey struct{}

MaxKey represents the BSON maxkey value.

type MinKey

type MinKey struct{}

MinKey represents the BSON minkey value.

type Null

type Null struct{}

Null represents the BSON null value.

type ObjectID

type ObjectID [12]byte

ObjectID is the BSON ObjectID type.

var NilObjectID ObjectID

NilObjectID is the zero value for ObjectID.

func NewObjectID

func NewObjectID() ObjectID

NewObjectID generates a new ObjectID.

func NewObjectIDFromTimestamp

func NewObjectIDFromTimestamp(timestamp time.Time) ObjectID

NewObjectIDFromTimestamp generates a new ObjectID based on the given time.

func ObjectIDFromHex

func ObjectIDFromHex(s string) (ObjectID, error)

ObjectIDFromHex creates a new ObjectID from a hex string. It returns an error if the hex string is not a valid ObjectID.

func (ObjectID) Hex

func (id ObjectID) Hex() string

Hex returns the hex encoding of the ObjectID as a string.

func (ObjectID) IsZero

func (id ObjectID) IsZero() bool

IsZero returns true if id is the empty ObjectID.

func (ObjectID) MarshalJSON

func (id ObjectID) MarshalJSON() ([]byte, error)

MarshalJSON returns the ObjectID as a string

func (ObjectID) MarshalText

func (id ObjectID) MarshalText() ([]byte, error)

MarshalText returns the ObjectID as UTF-8-encoded text. Implementing this allows us to use ObjectID as a map key when marshalling JSON. See https://pkg.go.dev/encoding#TextMarshaler

func (ObjectID) String

func (id ObjectID) String() string

func (ObjectID) Timestamp

func (id ObjectID) Timestamp() time.Time

Timestamp extracts the time part of the ObjectId.

func (*ObjectID) UnmarshalJSON

func (id *ObjectID) UnmarshalJSON(b []byte) error

UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it will be populated with the hex representation of the ObjectID. If the byte slice is 12 bytes long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and decodes them as NilObjectID.

As a special case UnmarshalJSON will decode a JSON object with key "$oid" that stores a hex encoded ObjectID: {"$oid": "65b3f7edd9bfca00daa6e3b31"}.

For any other inputs, an error will be returned.

func (*ObjectID) UnmarshalText

func (id *ObjectID) UnmarshalText(b []byte) error

UnmarshalText populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it will be populated with the hex representation of the ObjectID. If the byte slice is 12 bytes long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and decodes them as NilObjectID.

For any other inputs, an error will be returned.

Implementing this allows us to use ObjectID as a map key when unmarshalling JSON. See https://pkg.go.dev/encoding#TextUnmarshaler

type Raw

type Raw []byte

Raw is a raw encoded BSON document. It can be used to delay BSON document decoding or precompute a BSON encoded document.

A Raw must be a full BSON document. Use the RawValue type for individual BSON values.

Example (Marshal)

This example uses Raw to add a precomputed BSON document during marshal.

package main

import (
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	precomputed, err := bson.Marshal(bson.M{"Precomputed": true})
	if err != nil {
		panic(err)
	}

	msg := struct {
		Message  string
		Metadata bson.Raw
	}{
		Message:  "Hello World!",
		Metadata: precomputed,
	}

	b, err := bson.Marshal(msg)
	if err != nil {
		panic(err)
	}
	// Print the Extended JSON by converting BSON to bson.Raw.
	fmt.Println(bson.Raw(b).String())

}
Output:

{"message": "Hello World!","metadata": {"Precomputed": true}}
Example (Unmarshal)

This example uses Raw to skip parsing a nested document in a BSON message.

package main

import (
	"fmt"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	b, err := bson.Marshal(bson.M{
		"Word":     "beach",
		"Synonyms": bson.A{"coast", "shore", "waterfront"},
	})
	if err != nil {
		panic(err)
	}

	var res struct {
		Word     string
		Synonyms bson.Raw // Don't parse the whole list, we just want to count the elements.
	}

	err = bson.Unmarshal(b, &res)
	if err != nil {
		panic(err)
	}
	elems, err := res.Synonyms.Elements()
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s, synonyms count: %d\n", res.Word, len(elems))

}
Output:

beach, synonyms count: 3

func ReadDocument

func ReadDocument(r io.Reader) (Raw, error)

ReadDocument reads a BSON document from the io.Reader and returns it as a bson.Raw. If the reader contains multiple BSON documents, only the first document is read.

func (Raw) Elements

func (r Raw) Elements() ([]RawElement, error)

Elements returns this document as a slice of elements. The returned slice will contain valid elements. If the document is not valid, the elements up to the invalid point will be returned along with an error.

func (Raw) Index

func (r Raw) Index(index uint) RawElement

Index searches for and retrieves the element at the given index. This method will panic if the document is invalid or if the index is out of bounds.

func (Raw) IndexErr

func (r Raw) IndexErr(index uint) (RawElement, error)

IndexErr searches for and retrieves the element at the given index.

func (Raw) Lookup

func (r Raw) Lookup(key ...string) RawValue

Lookup search the document, potentially recursively, for the given key. If there are multiple keys provided, this method will recurse down, as long as the top and intermediate nodes are either documents or arrays.If an error occurs or if the value doesn't exist, an empty RawValue is returned.

func (Raw) LookupErr

func (r Raw) LookupErr(key ...string) (RawValue, error)

LookupErr searches the document and potentially subdocuments or arrays for the provided key. Each key provided to this method represents a layer of depth.

func (Raw) String

func (r Raw) String() string

String returns the BSON document encoded as Extended JSON.

func (Raw) Validate

func (r Raw) Validate() (err error)

Validate validates the document. This method only validates the first document in the slice, to validate other documents, the slice must be resliced.

Example
rdr := make(Raw, 500)
rdr[250], rdr[251], rdr[252], rdr[253], rdr[254] = '\x05', '\x00', '\x00', '\x00', '\x00'
err := rdr[250:].Validate()
fmt.Println(err)
Output:

<nil>

func (Raw) Values

func (r Raw) Values() ([]RawValue, error)

Values returns this document as a slice of values. The returned slice will contain valid values. If the document is not valid, the values up to the invalid point will be returned along with an error.

type RawArray

type RawArray []byte

RawArray is a raw bytes representation of a BSON array.

func ReadArray

func ReadArray(r io.Reader) (RawArray, error)

ReadArray reads a BSON array from the io.Reader and returns it as a bson.RawArray.

func (RawArray) DebugString

func (a RawArray) DebugString() string

DebugString outputs a human readable version of Array. It will attempt to stringify the valid components of the array even if the entire array is not valid.

func (RawArray) Index

func (a RawArray) Index(index uint) RawValue

Index searches for and retrieves the value at the given index. This method will panic if the array is invalid or if the index is out of bounds.

func (RawArray) IndexErr

func (a RawArray) IndexErr(index uint) (RawValue, error)

IndexErr searches for and retrieves the value at the given index.

func (RawArray) String

func (a RawArray) String() string

String outputs an ExtendedJSON version of Array. If the Array is not valid, this method returns an empty string.

func (RawArray) Validate

func (a RawArray) Validate() error

Validate validates the array and ensures the elements contained within are valid.

func (RawArray) Values

func (a RawArray) Values() ([]RawValue, error)

Values returns this array as a slice of values. The returned slice will contain valid values. If the array is not valid, the values up to the invalid point will be returned along with an error.

type RawElement

type RawElement []byte

RawElement is a raw encoded BSON document or array element.

func (RawElement) DebugString

func (re RawElement) DebugString() string

DebugString outputs a human readable version of RawElement. It will attempt to stringify the valid components of the element even if the entire element is not valid.

func (RawElement) Key

func (re RawElement) Key() string

Key returns the key for this element. If the element is not valid, this method returns an empty string. If knowing if the element is valid is important, use KeyErr.

func (RawElement) KeyErr

func (re RawElement) KeyErr() (string, error)

KeyErr returns the key for this element, returning an error if the element is not valid.

func (RawElement) String

func (re RawElement) String() string

String returns the BSON element encoded as Extended JSON.

func (RawElement) Validate

func (re RawElement) Validate() error

Validate ensures re is a valid BSON element.

func (RawElement) Value

func (re RawElement) Value() RawValue

Value returns the value of this element. If the element is not valid, this method returns an empty Value. If knowing if the element is valid is important, use ValueErr.

func (RawElement) ValueErr

func (re RawElement) ValueErr() (RawValue, error)

ValueErr returns the value for this element, returning an error if the element is not valid.

type RawValue

type RawValue struct {
	Type  Type
	Value []byte
	// contains filtered or unexported fields
}

RawValue is a raw encoded BSON value. It can be used to delay BSON value decoding or precompute BSON encoded value. Type is the BSON type of the value and Value is the raw encoded BSON value.

A RawValue must be an individual BSON value. Use the Raw type for full BSON documents.

Example (Marshal)

This example uses RawValue to add a precomputed BSON string value during marshal.

package main

import (
	"fmt"
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	t, val, err := bson.MarshalValue("Precomputed message!")
	if err != nil {
		panic(err)
	}
	precomputed := bson.RawValue{
		Type:  t,
		Value: val,
	}

	msg := struct {
		Message bson.RawValue
		Time    time.Time
	}{
		Message: precomputed,
		Time:    time.Unix(1675282389, 0),
	}

	b, err := bson.Marshal(msg)
	if err != nil {
		panic(err)
	}
	// Print the Extended JSON by converting BSON to bson.Raw.
	fmt.Println(bson.Raw(b).String())

}
Output:

{"message": "Precomputed message!","time": {"$date":{"$numberLong":"1675282389000"}}}
Example (Unmarshal)

This example uses RawValue to delay parsing a value in a BSON message.

package main

import (
	"fmt"
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	b1, err := bson.Marshal(bson.M{
		"Format":    "UNIX",
		"Timestamp": 1675282389,
	})
	if err != nil {
		panic(err)
	}

	b2, err := bson.Marshal(bson.M{
		"Format":    "RFC3339",
		"Timestamp": time.Unix(1675282389, 0).Format(time.RFC3339),
	})
	if err != nil {
		panic(err)
	}

	for _, b := range [][]byte{b1, b2} {
		var res struct {
			Format    string
			Timestamp bson.RawValue // Delay parsing until we know the timestamp format.
		}

		err = bson.Unmarshal(b, &res)
		if err != nil {
			panic(err)
		}

		var t time.Time
		switch res.Format {
		case "UNIX":
			t = time.Unix(res.Timestamp.AsInt64(), 0)
		case "RFC3339":
			t, err = time.Parse(time.RFC3339, res.Timestamp.StringValue())
			if err != nil {
				panic(err)
			}
		}
		fmt.Println(res.Format, t.Unix())
	}

}
Output:

UNIX 1675282389
RFC3339 1675282389

func (RawValue) Array

func (rv RawValue) Array() RawArray

Array returns the BSON array the Value represents as an Array. It panics if the value is a BSON type other than array.

func (RawValue) ArrayOK

func (rv RawValue) ArrayOK() (RawArray, bool)

ArrayOK is the same as Array, except it returns a boolean instead of panicking.

func (RawValue) AsInt64

func (rv RawValue) AsInt64() int64

AsInt64 returns a BSON number as an int64. If the BSON type is not a numeric one, this method will panic.

func (RawValue) AsInt64OK

func (rv RawValue) AsInt64OK() (int64, bool)

AsInt64OK is the same as AsInt64, except that it returns a boolean instead of panicking.

func (RawValue) Binary

func (rv RawValue) Binary() (subtype byte, data []byte)

Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type other than binary.

func (RawValue) BinaryOK

func (rv RawValue) BinaryOK() (subtype byte, data []byte, ok bool)

BinaryOK is the same as Binary, except it returns a boolean instead of panicking.

func (RawValue) Boolean

func (rv RawValue) Boolean() bool

Boolean returns the boolean value the Value represents. It panics if the value is a BSON type other than boolean.

func (RawValue) BooleanOK

func (rv RawValue) BooleanOK() (bool, bool)

BooleanOK is the same as Boolean, except it returns a boolean instead of panicking.

func (RawValue) CodeWithScope

func (rv RawValue) CodeWithScope() (string, Raw)

CodeWithScope returns the BSON JavaScript code with scope the Value represents. It panics if the value is a BSON type other than JavaScript code with scope.

func (RawValue) CodeWithScopeOK

func (rv RawValue) CodeWithScopeOK() (string, Raw, bool)

CodeWithScopeOK is the same as CodeWithScope, except that it returns a boolean instead of panicking.

func (RawValue) DBPointer

func (rv RawValue) DBPointer() (string, ObjectID)

DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON type other than DBPointer.

func (RawValue) DBPointerOK

func (rv RawValue) DBPointerOK() (string, ObjectID, bool)

DBPointerOK is the same as DBPoitner, except that it returns a boolean instead of panicking.

func (RawValue) DateTime

func (rv RawValue) DateTime() int64

DateTime returns the BSON datetime value the Value represents as a unix timestamp. It panics if the value is a BSON type other than datetime.

func (RawValue) DateTimeOK

func (rv RawValue) DateTimeOK() (int64, bool)

DateTimeOK is the same as DateTime, except it returns a boolean instead of panicking.

func (RawValue) DebugString

func (rv RawValue) DebugString() string

DebugString outputs a human readable version of Document. It will attempt to stringify the valid components of the document even if the entire document is not valid.

func (RawValue) Decimal128

func (rv RawValue) Decimal128() Decimal128

Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than decimal.

func (RawValue) Decimal128OK

func (rv RawValue) Decimal128OK() (Decimal128, bool)

Decimal128OK is the same as Decimal128, except that it returns a boolean instead of panicking.

func (RawValue) Document

func (rv RawValue) Document() Raw

Document returns the BSON document the Value represents as a Document. It panics if the value is a BSON type other than document.

func (RawValue) DocumentOK

func (rv RawValue) DocumentOK() (Raw, bool)

DocumentOK is the same as Document, except it returns a boolean instead of panicking.

func (RawValue) Double

func (rv RawValue) Double() float64

Double returns the float64 value for this element. It panics if e's BSON type is not bson.TypeDouble.

func (RawValue) DoubleOK

func (rv RawValue) DoubleOK() (float64, bool)

DoubleOK is the same as Double, but returns a boolean instead of panicking.

func (RawValue) Equal

func (rv RawValue) Equal(rv2 RawValue) bool

Equal compares rv and rv2 and returns true if they are equal.

func (RawValue) Int32

func (rv RawValue) Int32() int32

Int32 returns the int32 the Value represents. It panics if the value is a BSON type other than int32.

func (RawValue) Int32OK

func (rv RawValue) Int32OK() (int32, bool)

Int32OK is the same as Int32, except that it returns a boolean instead of panicking.

func (RawValue) Int64

func (rv RawValue) Int64() int64

Int64 returns the int64 the Value represents. It panics if the value is a BSON type other than int64.

func (RawValue) Int64OK

func (rv RawValue) Int64OK() (int64, bool)

Int64OK is the same as Int64, except that it returns a boolean instead of panicking.

func (RawValue) IsNumber

func (rv RawValue) IsNumber() bool

IsNumber returns true if the type of v is a numeric BSON type.

func (RawValue) IsZero

func (rv RawValue) IsZero() bool

IsZero reports whether the RawValue is zero, i.e. no data is present on the RawValue. It returns true if Type is 0 and Value is empty or nil.

func (RawValue) JavaScript

func (rv RawValue) JavaScript() string

JavaScript returns the BSON JavaScript code value the Value represents. It panics if the value is a BSON type other than JavaScript code.

func (RawValue) JavaScriptOK

func (rv RawValue) JavaScriptOK() (string, bool)

JavaScriptOK is the same as Javascript, excepti that it returns a boolean instead of panicking.

func (RawValue) ObjectID

func (rv RawValue) ObjectID() ObjectID

ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON type other than objectid.

func (RawValue) ObjectIDOK

func (rv RawValue) ObjectIDOK() (ObjectID, bool)

ObjectIDOK is the same as ObjectID, except it returns a boolean instead of panicking.

func (RawValue) Regex

func (rv RawValue) Regex() (pattern, options string)

Regex returns the BSON regex value the Value represents. It panics if the value is a BSON type other than regex.

func (RawValue) RegexOK

func (rv RawValue) RegexOK() (pattern, options string, ok bool)

RegexOK is the same as Regex, except it returns a boolean instead of panicking.

func (RawValue) String

func (rv RawValue) String() string

String implements the fmt.String interface. This method will return values in extended JSON format. If the value is not valid, this returns an empty string

func (RawValue) StringValue

func (rv RawValue) StringValue() string

StringValue returns the string value for this element. It panics if e's BSON type is not bson.TypeString.

NOTE: This method is called StringValue to avoid a collision with the String method which implements the fmt.Stringer interface.

func (RawValue) StringValueOK

func (rv RawValue) StringValueOK() (string, bool)

StringValueOK is the same as StringValue, but returns a boolean instead of panicking.

func (RawValue) Symbol

func (rv RawValue) Symbol() string

Symbol returns the BSON symbol value the Value represents. It panics if the value is a BSON type other than symbol.

func (RawValue) SymbolOK

func (rv RawValue) SymbolOK() (string, bool)

SymbolOK is the same as Symbol, excepti that it returns a boolean instead of panicking.

func (RawValue) Time

func (rv RawValue) Time() time.Time

Time returns the BSON datetime value the Value represents. It panics if the value is a BSON type other than datetime.

func (RawValue) TimeOK

func (rv RawValue) TimeOK() (time.Time, bool)

TimeOK is the same as Time, except it returns a boolean instead of panicking.

func (RawValue) Timestamp

func (rv RawValue) Timestamp() (t, i uint32)

Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a BSON type other than timestamp.

func (RawValue) TimestampOK

func (rv RawValue) TimestampOK() (t, i uint32, ok bool)

TimestampOK is the same as Timestamp, except that it returns a boolean instead of panicking.

func (RawValue) Unmarshal

func (rv RawValue) Unmarshal(val interface{}) error

Unmarshal deserializes BSON into the provided val. If RawValue cannot be unmarshaled into val, an error is returned. This method will use the registry used to create the RawValue, if the RawValue was created from partial BSON processing, or it will use the default registry. Users wishing to specify the registry to use should use UnmarshalWithRegistry.

func (RawValue) UnmarshalWithContext

func (rv RawValue) UnmarshalWithContext(dc *DecodeContext, val interface{}) error

UnmarshalWithContext performs the same unmarshalling as Unmarshal but uses the provided DecodeContext instead of the one attached or the default registry.

func (RawValue) UnmarshalWithRegistry

func (rv RawValue) UnmarshalWithRegistry(r *Registry, val interface{}) error

UnmarshalWithRegistry performs the same unmarshalling as Unmarshal but uses the provided registry instead of the one attached or the default registry.

func (RawValue) Validate

func (rv RawValue) Validate() error

Validate ensures the value is a valid BSON value.

type Regex

type Regex struct {
	Pattern string
	Options string
}

Regex represents a BSON regex value.

func (Regex) Equal

func (rp Regex) Equal(rp2 Regex) bool

Equal compares rp to rp2 and returns true if they are equal.

func (Regex) IsZero

func (rp Regex) IsZero() bool

IsZero returns if rp is the empty Regex.

func (Regex) String

func (rp Regex) String() string

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

A Registry is a store for ValueEncoders, ValueDecoders, and a type map. See the Registry type documentation for examples of registering various custom encoders and decoders. A Registry can have four main types of codecs:

1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and RegisterTypeDecoder methods. The registered codec will be invoked when encoding/decoding a value whose type matches the registered type exactly. If the registered type is an interface, the codec will be invoked when encoding or decoding values whose type is the interface, but not for values with concrete types that implement the interface.

2. Interface encoders/decoders - These can be registered using the RegisterInterfaceEncoder and RegisterInterfaceDecoder methods. These methods only accept interface types and the registered codecs will be invoked when encoding or decoding values whose types implement the interface. An example of an interface defined by the driver is bson.Marshaler. The driver will call the MarshalBSON method for any value whose type implements bson.Marshaler, regardless of the value's concrete type.

3. Type map entries - This can be used to associate a BSON type with a Go type. These type associations are used when decoding into a bson.D/bson.M or a struct field of type interface{}. For example, by default, BSON int32 and int64 values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would change the behavior so these values decode as Go int instances instead:

intType := reflect.TypeOf(int(0))
registry.RegisterTypeMapEntry(bson.TypeInt32, intType).RegisterTypeMapEntry(bson.TypeInt64, intType)

4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the registered reflect.Kind as long as the value's type doesn't match a registered type or interface encoder/decoder first. These methods should be used to change the behavior for all values for a specific kind.

Read Registry.LookupDecoder and Registry.LookupEncoder for Registry lookup procedure.

Example (CustomDecoder)
package main

import (
	"bytes"
	"fmt"
	"reflect"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create a custom decoder for a boolean type that can be stored in the
	// database as a BSON boolean, int32, or int64. For our custom decoder, BSON
	// int32 or int64 values are considered "true" if they are non-zero.
	type lenientBool bool

	lenientBoolType := reflect.TypeOf(lenientBool(true))

	lenientBoolDecoder := func(
		_ bson.DecodeContext,
		vr bson.ValueReader,
		val reflect.Value,
	) error {
		// All decoder implementations should check that val is valid, settable,
		// and is of the correct kind before proceeding.
		if !val.IsValid() || !val.CanSet() || val.Type() != lenientBoolType {
			return bson.ValueDecoderError{
				Name:     "lenientBoolDecoder",
				Types:    []reflect.Type{lenientBoolType},
				Received: val,
			}
		}

		var result bool
		switch vr.Type() {
		case bson.TypeBoolean:
			b, err := vr.ReadBoolean()
			if err != nil {
				return err
			}
			result = b
		case bson.TypeInt32:
			i32, err := vr.ReadInt32()
			if err != nil {
				return err
			}
			result = i32 != 0
		case bson.TypeInt64:
			i64, err := vr.ReadInt64()
			if err != nil {
				return err
			}
			result = i64 != 0
		default:
			return fmt.Errorf(
				"received invalid BSON type to decode into lenientBool: %s",
				vr.Type())
		}

		val.SetBool(result)
		return nil
	}

	reg := bson.NewRegistry()
	reg.RegisterTypeDecoder(
		lenientBoolType,
		bson.ValueDecoderFunc(lenientBoolDecoder))

	// Marshal a BSON document with a single field "isOK" that is a non-zero
	// integer value.
	b, err := bson.Marshal(bson.M{"isOK": 1})
	if err != nil {
		panic(err)
	}

	// Now try to decode the BSON document to a struct with a field "IsOK" that
	// is type lenientBool. Expect that the non-zero integer value is decoded
	// as boolean true.
	type MyDocument struct {
		IsOK lenientBool `bson:"isOK"`
	}
	var doc MyDocument
	dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(b)))
	dec.SetRegistry(reg)
	err = dec.Decode(&doc)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", doc)
}
Output:

{IsOK:true}
Example (CustomEncoder)
package main

import (
	"bytes"
	"fmt"
	"math"
	"reflect"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create a custom encoder for an integer type that multiplies the input
	// value by -1 when encoding.
	type negatedInt int

	negatedIntType := reflect.TypeOf(negatedInt(0))

	negatedIntEncoder := func(
		_ bson.EncodeContext,
		vw bson.ValueWriter,
		val reflect.Value,
	) error {
		// All encoder implementations should check that val is valid and is of
		// the correct type before proceeding.
		if !val.IsValid() || val.Type() != negatedIntType {
			return bson.ValueEncoderError{
				Name:     "negatedIntEncoder",
				Types:    []reflect.Type{negatedIntType},
				Received: val,
			}
		}

		// Negate val and encode as a BSON int32 if it can fit in 32 bits and a
		// BSON int64 otherwise.
		negatedVal := val.Int() * -1
		if math.MinInt32 <= negatedVal && negatedVal <= math.MaxInt32 {
			return vw.WriteInt32(int32(negatedVal))
		}
		return vw.WriteInt64(negatedVal)
	}

	reg := bson.NewRegistry()
	reg.RegisterTypeEncoder(
		negatedIntType,
		bson.ValueEncoderFunc(negatedIntEncoder))

	// Define a document that includes both int and negatedInt fields with the
	// same value.
	type myDocument struct {
		Int        int
		NegatedInt negatedInt
	}
	doc := myDocument{
		Int:        1,
		NegatedInt: 1,
	}

	// Marshal the document as BSON. Expect that the int field is encoded to the
	// same value and that the negatedInt field is encoded as the negated value.
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	enc := bson.NewEncoder(vw)
	enc.SetRegistry(reg)
	err := enc.Encode(doc)
	if err != nil {
		panic(err)
	}
	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"int": {"$numberInt":"1"},"negatedint": {"$numberInt":"-1"}}

func NewMgoRegistry

func NewMgoRegistry() *Registry

NewMgoRegistry creates a new bson.Registry configured with the default encoders and decoders.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty Registry.

func NewRespectNilValuesMgoRegistry

func NewRespectNilValuesMgoRegistry() *Registry

NewRespectNilValuesMgoRegistry creates a new bson.Registry configured to behave like mgo/bson with RespectNilValues set to true.

func (*Registry) LookupDecoder

func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error)

LookupDecoder returns the first matching decoder in the Registry. It uses the following lookup order:

1. A decoder registered for the exact type. If the given type is an interface, a decoder registered using RegisterTypeDecoder for that interface will be selected.

2. A decoder registered using RegisterInterfaceDecoder for an interface implemented by the type or by a pointer to the type. If the value matches multiple interfaces (e.g. the type implements bson.Unmarshaler and bson.ValueUnmarshaler), the first one registered will be selected. Note that registries constructed using bson.NewRegistry have driver-defined interfaces registered for the bson.Unmarshaler and bson.ValueUnmarshaler interfaces, so those will take precedence over any new interfaces.

3. A decoder registered using RegisterKindDecoder for the kind of value.

If no decoder is found, an error of type ErrNoDecoder is returned. LookupDecoder is safe for concurrent use by multiple goroutines after all codecs and decoders are registered.

func (*Registry) LookupEncoder

func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error)

LookupEncoder returns the first matching encoder in the Registry. It uses the following lookup order:

1. An encoder registered for the exact type. If the given type is an interface, an encoder registered using RegisterTypeEncoder for that interface will be selected.

2. An encoder registered using RegisterInterfaceEncoder for an interface implemented by the type or by a pointer to the type. If the value matches multiple interfaces (e.g. the type implements bson.Marshaler and bson.ValueMarshaler), the first one registered will be selected. Note that registries constructed using bson.NewRegistry have driver-defined interfaces registered for the bson.Marshaler, bson.ValueMarshaler, and bson.Proxy interfaces, so those will take precedence over any new interfaces.

3. An encoder registered using RegisterKindEncoder for the kind of value.

If no encoder is found, an error of type ErrNoEncoder is returned. LookupEncoder is safe for concurrent use by multiple goroutines after all codecs and encoders are registered.

func (*Registry) LookupTypeMapEntry

func (r *Registry) LookupTypeMapEntry(bt Type) (reflect.Type, error)

LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON type. If no type is found, ErrNoTypeMapEntry is returned.

LookupTypeMapEntry should not be called concurrently with any other Registry method.

func (*Registry) RegisterInterfaceDecoder

func (r *Registry) RegisterInterfaceDecoder(iface reflect.Type, dec ValueDecoder)

RegisterInterfaceDecoder registers an decoder for the provided interface type iface. This decoder will be called when unmarshaling into a type if the type implements iface or a pointer to the type implements iface. If the provided type is not an interface (i.e. iface.Kind() != reflect.Interface), this method will panic.

RegisterInterfaceDecoder should not be called concurrently with any other Registry method.

func (*Registry) RegisterInterfaceEncoder

func (r *Registry) RegisterInterfaceEncoder(iface reflect.Type, enc ValueEncoder)

RegisterInterfaceEncoder registers an encoder for the provided interface type iface. This encoder will be called when marshaling a type if the type implements iface or a pointer to the type implements iface. If the provided type is not an interface (i.e. iface.Kind() != reflect.Interface), this method will panic.

RegisterInterfaceEncoder should not be called concurrently with any other Registry method.

func (*Registry) RegisterKindDecoder

func (r *Registry) RegisterKindDecoder(kind reflect.Kind, dec ValueDecoder)

RegisterKindDecoder registers the provided ValueDecoder for the provided kind.

Use RegisterKindDecoder to register a decoder for any type with the same underlying kind. For example, consider the type MyInt defined as

type MyInt int32

To define an decoder for MyInt and int32, use RegisterKindDecoder like

reg.RegisterKindDecoder(reflect.Int32, myDecoder)

RegisterKindDecoder should not be called concurrently with any other Registry method.

Example
package main

import (
	"bytes"
	"fmt"
	"reflect"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create a custom decoder that can decode any integer value, including
	// integer values encoded as floating point numbers, to any Go type
	// with underlying type int64. To do that, we register the decoder as a
	// "kind" decoder for kind reflect.Int64. That way, we can even decode to
	// user-defined types with underlying type int64.
	flexibleInt64KindDecoder := func(
		_ bson.DecodeContext,
		vr bson.ValueReader,
		val reflect.Value,
	) error {
		// All decoder implementations should check that val is valid, settable,
		// and is of the correct kind before proceeding.
		if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Int64 {
			return bson.ValueDecoderError{
				Name:     "flexibleInt64KindDecoder",
				Kinds:    []reflect.Kind{reflect.Int64},
				Received: val,
			}
		}

		var result int64
		switch vr.Type() {
		case bson.TypeInt64:
			i64, err := vr.ReadInt64()
			if err != nil {
				return err
			}
			result = i64
		case bson.TypeInt32:
			i32, err := vr.ReadInt32()
			if err != nil {
				return err
			}
			result = int64(i32)
		case bson.TypeDouble:
			d, err := vr.ReadDouble()
			if err != nil {
				return err
			}
			i64 := int64(d)
			// Make sure the double field is an integer value.
			if d != float64(i64) {
				return fmt.Errorf("double %f is not an integer value", d)
			}
			result = i64
		default:
			return fmt.Errorf(
				"received invalid BSON type to decode into int64: %s",
				vr.Type())
		}

		val.SetInt(result)
		return nil
	}

	reg := bson.NewRegistry()
	reg.RegisterKindDecoder(
		reflect.Int64,
		bson.ValueDecoderFunc(flexibleInt64KindDecoder))

	// Marshal a BSON document with fields that are mixed numeric types but all
	// hold integer values (i.e. values with no fractional part).
	b, err := bson.Marshal(bson.M{"myInt": float64(8), "int64": int32(9)})
	if err != nil {
		panic(err)
	}

	// Now try to decode the BSON document to a struct with fields
	// that is type int32. Expect that the float value is successfully decoded.
	type myInt int64
	type myDocument struct {
		MyInt myInt
		Int64 int64
	}
	var doc myDocument
	dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(b)))
	dec.SetRegistry(reg)
	err = dec.Decode(&doc)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", doc)
}
Output:

{MyInt:8 Int64:9}

func (*Registry) RegisterKindEncoder

func (r *Registry) RegisterKindEncoder(kind reflect.Kind, enc ValueEncoder)

RegisterKindEncoder registers the provided ValueEncoder for the provided kind.

Use RegisterKindEncoder to register an encoder for any type with the same underlying kind. For example, consider the type MyInt defined as

type MyInt int32

To define an encoder for MyInt and int32, use RegisterKindEncoder like

reg.RegisterKindEncoder(reflect.Int32, myEncoder)

RegisterKindEncoder should not be called concurrently with any other Registry method.

Example
package main

import (
	"bytes"
	"fmt"
	"reflect"

	"go.mongodb.org/mongo-driver/v2/bson"
)

func main() {
	// Create a custom encoder that writes any Go type that has underlying type
	// int32 as an a BSON int64. To do that, we register the encoder as a "kind"
	// encoder for kind reflect.Int32. That way, even user-defined types with
	// underlying type int32 will be encoded as a BSON int64.
	int32To64Encoder := func(
		_ bson.EncodeContext,
		vw bson.ValueWriter,
		val reflect.Value,
	) error {
		// All encoder implementations should check that val is valid and is of
		// the correct type or kind before proceeding.
		if !val.IsValid() || val.Kind() != reflect.Int32 {
			return bson.ValueEncoderError{
				Name:     "int32To64Encoder",
				Kinds:    []reflect.Kind{reflect.Int32},
				Received: val,
			}
		}

		return vw.WriteInt64(val.Int())
	}

	// Create a default registry and register our int32-to-int64 encoder for
	// kind reflect.Int32.
	reg := bson.NewRegistry()
	reg.RegisterKindEncoder(
		reflect.Int32,
		bson.ValueEncoderFunc(int32To64Encoder))

	// Define a document that includes an int32, an int64, and a user-defined
	// type "myInt" that has underlying type int32.
	type myInt int32
	type myDocument struct {
		MyInt myInt
		Int32 int32
		Int64 int64
	}
	doc := myDocument{
		Int32: 1,
		Int64: 1,
		MyInt: 1,
	}

	// Marshal the document as BSON. Expect that all fields are encoded as BSON
	// int64 (represented as "$numberLong" when encoded as Extended JSON).
	buf := new(bytes.Buffer)
	vw := bson.NewDocumentWriter(buf)
	enc := bson.NewEncoder(vw)
	enc.SetRegistry(reg)
	err := enc.Encode(doc)
	if err != nil {
		panic(err)
	}
	fmt.Println(bson.Raw(buf.Bytes()).String())
}
Output:

{"myint": {"$numberLong":"1"},"int32": {"$numberLong":"1"},"int64": {"$numberLong":"1"}}

func (*Registry) RegisterTypeDecoder

func (r *Registry) RegisterTypeDecoder(valueType reflect.Type, dec ValueDecoder)

RegisterTypeDecoder registers the provided ValueDecoder for the provided type.

The type will be used as provided, so a decoder can be registered for a type and a different decoder can be registered for a pointer to that type.

If the given type is an interface, the decoder will be called when unmarshaling into a type that is that interface. It will not be called when unmarshaling into a non-interface type that implements the interface. To get the latter behavior, call RegisterHookDecoder instead.

RegisterTypeDecoder should not be called concurrently with any other Registry method.

func (*Registry) RegisterTypeEncoder

func (r *Registry) RegisterTypeEncoder(valueType reflect.Type, enc ValueEncoder)

RegisterTypeEncoder registers the provided ValueEncoder for the provided type.

The type will be used as provided, so an encoder can be registered for a type and a different encoder can be registered for a pointer to that type.

If the given type is an interface, the encoder will be called when marshaling a type that is that interface. It will not be called when marshaling a non-interface type that implements the interface. To get the latter behavior, call RegisterHookEncoder instead.

RegisterTypeEncoder should not be called concurrently with any other Registry method.

func (*Registry) RegisterTypeMapEntry

func (r *Registry) RegisterTypeMapEntry(bt Type, rt reflect.Type)

RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this mapping is decoding situations where an empty interface is used and a default type needs to be created and decoded into.

By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON documents, a type map entry for TypeEmbeddedDocument should be registered. For example, to force BSON documents to decode to bson.Raw, use the following code:

reg.RegisterTypeMapEntry(TypeEmbeddedDocument, reflect.TypeOf(bson.Raw{}))

type Symbol

type Symbol string

Symbol represents a BSON symbol value.

type Timestamp

type Timestamp struct {
	T uint32
	I uint32
}

Timestamp represents a BSON timestamp value.

func (Timestamp) After

func (tp Timestamp) After(tp2 Timestamp) bool

After reports whether the time instant tp is after tp2.

func (Timestamp) Before

func (tp Timestamp) Before(tp2 Timestamp) bool

Before reports whether the time instant tp is before tp2.

func (Timestamp) Compare

func (tp Timestamp) Compare(tp2 Timestamp) int

Compare compares the time instant tp with tp2. If tp is before tp2, it returns -1; if tp is after tp2, it returns +1; if they're the same, it returns 0.

func (Timestamp) Equal

func (tp Timestamp) Equal(tp2 Timestamp) bool

Equal compares tp to tp2 and returns true if they are equal.

func (Timestamp) IsZero

func (tp Timestamp) IsZero() bool

IsZero returns if tp is the zero Timestamp.

type TransitionError

type TransitionError struct {
	// contains filtered or unexported fields
}

TransitionError is an error returned when an invalid progressing a ValueReader or ValueWriter state machine occurs.

func (TransitionError) Error

func (te TransitionError) Error() string

type Type

type Type byte

Type represents a BSON type.

const (
	TypeDouble           Type = 0x01
	TypeString           Type = 0x02
	TypeEmbeddedDocument Type = 0x03
	TypeArray            Type = 0x04
	TypeBinary           Type = 0x05
	TypeUndefined        Type = 0x06
	TypeObjectID         Type = 0x07
	TypeBoolean          Type = 0x08
	TypeDateTime         Type = 0x09
	TypeNull             Type = 0x0A
	TypeRegex            Type = 0x0B
	TypeDBPointer        Type = 0x0C
	TypeJavaScript       Type = 0x0D
	TypeSymbol           Type = 0x0E
	TypeCodeWithScope    Type = 0x0F
	TypeInt32            Type = 0x10
	TypeTimestamp        Type = 0x11
	TypeInt64            Type = 0x12
	TypeDecimal128       Type = 0x13
	TypeMaxKey           Type = 0x7F
	TypeMinKey           Type = 0xFF
)

BSON element types as described in https://bsonspec.org/spec.html.

func MarshalValue

func MarshalValue(val interface{}) (Type, []byte, error)

MarshalValue returns the BSON encoding of val.

MarshalValue will use bson.NewRegistry() to transform val into a BSON value. If val is a struct, this function will inspect struct tags and alter the marshalling process accordingly.

func (Type) IsValid

func (bt Type) IsValid() bool

IsValid will return true if the Type is valid.

func (Type) String

func (bt Type) String() string

String returns the string representation of the BSON type's name.

type Undefined

type Undefined struct{}

Undefined represents the BSON undefined value type.

type Unmarshaler

type Unmarshaler interface {
	UnmarshalBSON([]byte) error
}

Unmarshaler is the interface implemented by types that can unmarshal a BSON document representation of themselves. The input can be assumed to be a valid encoding of a BSON document. UnmarshalBSON must copy the JSON data if it wishes to retain the data after returning.

Unmarshaler is only used to unmarshal full BSON documents. To create custom BSON unmarshaling behavior for individual values in a BSON document, implement the ValueUnmarshaler interface instead.

type ValueDecoder

type ValueDecoder interface {
	DecodeValue(DecodeContext, ValueReader, reflect.Value) error
}

ValueDecoder is the interface implemented by types that can decode BSON to a provided Go type. Implementations should ensure that the value they receive is settable. Similar to ValueEncoderFunc, ValueDecoderFunc is provided to allow the use of a function with the correct signature as a ValueDecoder. A DecodeContext instance is provided and serves similar functionality to the EncodeContext.

Example
var _ ValueDecoderFunc = func(_ DecodeContext, vr ValueReader, val reflect.Value) error {
	if !val.CanSet() || val.Kind() != reflect.String {
		return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val}
	}

	if vr.Type() != TypeString {
		return fmt.Errorf("cannot decode %v into a string type", vr.Type())
	}

	str, err := vr.ReadString()
	if err != nil {
		return err
	}
	val.SetString(str)
	return nil
}
Output:

type ValueDecoderError

type ValueDecoderError struct {
	Name     string
	Types    []reflect.Type
	Kinds    []reflect.Kind
	Received reflect.Value
}

ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be decoded by the ValueDecoder.

func (ValueDecoderError) Error

func (vde ValueDecoderError) Error() string

type ValueDecoderFunc

type ValueDecoderFunc func(DecodeContext, ValueReader, reflect.Value) error

ValueDecoderFunc is an adapter function that allows a function with the correct signature to be used as a ValueDecoder.

func (ValueDecoderFunc) DecodeValue

func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error

DecodeValue implements the ValueDecoder interface.

type ValueEncoder

type ValueEncoder interface {
	EncodeValue(EncodeContext, ValueWriter, reflect.Value) error
}

ValueEncoder is the interface implemented by types that can encode a provided Go type to BSON. The value to encode is provided as a reflect.Value and a bson.ValueWriter is used within the EncodeValue method to actually create the BSON representation. For convenience, ValueEncoderFunc is provided to allow use of a function with the correct signature as a ValueEncoder. An EncodeContext instance is provided to allow implementations to lookup further ValueEncoders and to provide configuration information.

Example
var _ ValueEncoderFunc = func(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
	if val.Kind() != reflect.String {
		return ValueEncoderError{Name: "StringEncodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val}
	}

	return vw.WriteString(val.String())
}
Output:

type ValueEncoderError

type ValueEncoderError struct {
	Name     string
	Types    []reflect.Type
	Kinds    []reflect.Kind
	Received reflect.Value
}

ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be encoded by the ValueEncoder.

func (ValueEncoderError) Error

func (vee ValueEncoderError) Error() string

type ValueEncoderFunc

type ValueEncoderFunc func(EncodeContext, ValueWriter, reflect.Value) error

ValueEncoderFunc is an adapter function that allows a function with the correct signature to be used as a ValueEncoder.

func (ValueEncoderFunc) EncodeValue

func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error

EncodeValue implements the ValueEncoder interface.

type ValueMarshaler

type ValueMarshaler interface {
	MarshalBSONValue() (typ byte, data []byte, err error)
}

ValueMarshaler is the interface implemented by types that can marshal themselves into a valid BSON value. The format of the returned bytes must match the returned type.

Implementations of ValueMarshaler must return an individual BSON value. To create custom BSON marshaling behavior for an entire BSON document, implement the Marshaler interface instead.

type ValueReader

type ValueReader interface {
	Type() Type
	Skip() error

	ReadArray() (ArrayReader, error)
	ReadBinary() (b []byte, btype byte, err error)
	ReadBoolean() (bool, error)
	ReadDocument() (DocumentReader, error)
	ReadCodeWithScope() (code string, dr DocumentReader, err error)
	ReadDBPointer() (ns string, oid ObjectID, err error)
	ReadDateTime() (int64, error)
	ReadDecimal128() (Decimal128, error)
	ReadDouble() (float64, error)
	ReadInt32() (int32, error)
	ReadInt64() (int64, error)
	ReadJavascript() (code string, err error)
	ReadMaxKey() error
	ReadMinKey() error
	ReadNull() error
	ReadObjectID() (ObjectID, error)
	ReadRegex() (pattern, options string, err error)
	ReadString() (string, error)
	ReadSymbol() (symbol string, err error)
	ReadTimestamp() (t, i uint32, err error)
	ReadUndefined() error
}

ValueReader is a generic interface used to read values from BSON. This type is implemented by several types with different underlying representations of BSON, such as a bson.Document, raw BSON bytes, or extended JSON.

func NewDocumentReader

func NewDocumentReader(r io.Reader) ValueReader

NewDocumentReader returns a ValueReader using b for the underlying BSON representation.

func NewExtJSONValueReader

func NewExtJSONValueReader(r io.Reader, canonicalOnly bool) (ValueReader, error)

NewExtJSONValueReader returns a ValueReader that reads Extended JSON values from r. If canonicalOnly is true, reading values from the ValueReader returns an error if the Extended JSON was not marshaled in canonical mode.

type ValueUnmarshaler

type ValueUnmarshaler interface {
	UnmarshalBSONValue(typ byte, data []byte) error
}

ValueUnmarshaler is the interface implemented by types that can unmarshal a BSON value representation of themselves. The input can be assumed to be a valid encoding of a BSON value. UnmarshalBSONValue must copy the BSON value bytes if it wishes to retain the data after returning.

ValueUnmarshaler is only used to unmarshal individual values in a BSON document. To create custom BSON unmarshaling behavior for an entire BSON document, implement the Unmarshaler interface instead.

type ValueWriter

type ValueWriter interface {
	WriteArray() (ArrayWriter, error)
	WriteBinary(b []byte) error
	WriteBinaryWithSubtype(b []byte, btype byte) error
	WriteBoolean(bool) error
	WriteCodeWithScope(code string) (DocumentWriter, error)
	WriteDBPointer(ns string, oid ObjectID) error
	WriteDateTime(dt int64) error
	WriteDecimal128(Decimal128) error
	WriteDouble(float64) error
	WriteInt32(int32) error
	WriteInt64(int64) error
	WriteJavascript(code string) error
	WriteMaxKey() error
	WriteMinKey() error
	WriteNull() error
	WriteObjectID(ObjectID) error
	WriteRegex(pattern, options string) error
	WriteString(string) error
	WriteDocument() (DocumentWriter, error)
	WriteSymbol(symbol string) error
	WriteTimestamp(t, i uint32) error
	WriteUndefined() error
}

ValueWriter is the interface used to write BSON values. Implementations of this interface handle creating BSON or BSON adjacent representations of the values.

func NewDocumentWriter

func NewDocumentWriter(w io.Writer) ValueWriter

NewDocumentWriter creates a ValueWriter that writes BSON to w.

This ValueWriter will only write entire documents to the io.Writer and it will buffer the document as it is built.

func NewExtJSONValueWriter

func NewExtJSONValueWriter(w io.Writer, canonical, escapeHTML bool) ValueWriter

NewExtJSONValueWriter creates a ValueWriter that writes Extended JSON to w.

type Zeroer

type Zeroer interface {
	IsZero() bool
}

Zeroer allows custom struct types to implement a report of zero state. All struct types that don't implement Zeroer or where IsZero returns false are considered to be not zero.

Directories

Path Synopsis
Package mgocompat provides Registry, a BSON registry compatible with globalsign/mgo's BSON, with some remaining differences.
Package mgocompat provides Registry, a BSON registry compatible with globalsign/mgo's BSON, with some remaining differences.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL