...

Source file src/go.mongodb.org/mongo-driver/bson/encoder_example_test.go

Documentation: go.mongodb.org/mongo-driver/bson

     1  // Copyright (C) MongoDB, Inc. 2023-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 bson_test
     8  
     9  import (
    10  	"bytes"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  
    15  	"go.mongodb.org/mongo-driver/bson"
    16  	"go.mongodb.org/mongo-driver/bson/bsonrw"
    17  )
    18  
    19  func ExampleEncoder() {
    20  	// Create an Encoder that writes BSON values to a bytes.Buffer.
    21  	buf := new(bytes.Buffer)
    22  	vw, err := bsonrw.NewBSONValueWriter(buf)
    23  	if err != nil {
    24  		panic(err)
    25  	}
    26  	encoder, err := bson.NewEncoder(vw)
    27  	if err != nil {
    28  		panic(err)
    29  	}
    30  
    31  	type Product struct {
    32  		Name  string `bson:"name"`
    33  		SKU   string `bson:"sku"`
    34  		Price int64  `bson:"price_cents"`
    35  	}
    36  
    37  	// Use the Encoder to marshal a BSON document that contains the name, SKU,
    38  	// and price (in cents) of a product.
    39  	product := Product{
    40  		Name:  "Cereal Rounds",
    41  		SKU:   "AB12345",
    42  		Price: 399,
    43  	}
    44  	err = encoder.Encode(product)
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  
    49  	// Print the BSON document as Extended JSON by converting it to bson.Raw.
    50  	fmt.Println(bson.Raw(buf.Bytes()).String())
    51  	// Output: {"name": "Cereal Rounds","sku": "AB12345","price_cents": {"$numberLong":"399"}}
    52  }
    53  
    54  type CityState struct {
    55  	City  string
    56  	State string
    57  }
    58  
    59  func (k CityState) String() string {
    60  	return fmt.Sprintf("%s, %s", k.City, k.State)
    61  }
    62  
    63  func ExampleEncoder_StringifyMapKeysWithFmt() {
    64  	// Create an Encoder that writes BSON values to a bytes.Buffer.
    65  	buf := new(bytes.Buffer)
    66  	vw, err := bsonrw.NewBSONValueWriter(buf)
    67  	if err != nil {
    68  		panic(err)
    69  	}
    70  	encoder, err := bson.NewEncoder(vw)
    71  	if err != nil {
    72  		panic(err)
    73  	}
    74  
    75  	// Configure the Encoder to convert Go map keys to BSON document field names
    76  	// using fmt.Sprintf instead of the default string conversion logic.
    77  	encoder.StringifyMapKeysWithFmt()
    78  
    79  	// Use the Encoder to marshal a BSON document that contains is a map of
    80  	// city and state to a list of zip codes in that city.
    81  	zipCodes := map[CityState][]int{
    82  		{City: "New York", State: "NY"}: {10001, 10301, 10451},
    83  	}
    84  	err = encoder.Encode(zipCodes)
    85  	if err != nil {
    86  		panic(err)
    87  	}
    88  
    89  	// Print the BSON document as Extended JSON by converting it to bson.Raw.
    90  	fmt.Println(bson.Raw(buf.Bytes()).String())
    91  	// Output: {"New York, NY": [{"$numberInt":"10001"},{"$numberInt":"10301"},{"$numberInt":"10451"}]}
    92  }
    93  
    94  func ExampleEncoder_UseJSONStructTags() {
    95  	// Create an Encoder that writes BSON values to a bytes.Buffer.
    96  	buf := new(bytes.Buffer)
    97  	vw, err := bsonrw.NewBSONValueWriter(buf)
    98  	if err != nil {
    99  		panic(err)
   100  	}
   101  	encoder, err := bson.NewEncoder(vw)
   102  	if err != nil {
   103  		panic(err)
   104  	}
   105  
   106  	type Product struct {
   107  		Name  string `json:"name"`
   108  		SKU   string `json:"sku"`
   109  		Price int64  `json:"price_cents"`
   110  	}
   111  
   112  	// Configure the Encoder to use "json" struct tags when decoding if "bson"
   113  	// struct tags are not present.
   114  	encoder.UseJSONStructTags()
   115  
   116  	// Use the Encoder to marshal a BSON document that contains the name, SKU,
   117  	// and price (in cents) of a product.
   118  	product := Product{
   119  		Name:  "Cereal Rounds",
   120  		SKU:   "AB12345",
   121  		Price: 399,
   122  	}
   123  	err = encoder.Encode(product)
   124  	if err != nil {
   125  		panic(err)
   126  	}
   127  
   128  	// Print the BSON document as Extended JSON by converting it to bson.Raw.
   129  	fmt.Println(bson.Raw(buf.Bytes()).String())
   130  	// Output: {"name": "Cereal Rounds","sku": "AB12345","price_cents": {"$numberLong":"399"}}
   131  }
   132  
   133  func ExampleEncoder_multipleBSONDocuments() {
   134  	// Create an Encoder that writes BSON values to a bytes.Buffer.
   135  	buf := new(bytes.Buffer)
   136  	vw, err := bsonrw.NewBSONValueWriter(buf)
   137  	if err != nil {
   138  		panic(err)
   139  	}
   140  	encoder, err := bson.NewEncoder(vw)
   141  	if err != nil {
   142  		panic(err)
   143  	}
   144  
   145  	type Coordinate struct {
   146  		X int
   147  		Y int
   148  	}
   149  
   150  	// Use the encoder to marshal 5 Coordinate values as a sequence of BSON
   151  	// documents.
   152  	for i := 0; i < 5; i++ {
   153  		err := encoder.Encode(Coordinate{
   154  			X: i,
   155  			Y: i + 1,
   156  		})
   157  		if err != nil {
   158  			panic(err)
   159  		}
   160  	}
   161  
   162  	// Read each marshaled BSON document from the buffer and print them as
   163  	// Extended JSON by converting them to bson.Raw.
   164  	for {
   165  		doc, err := bson.ReadDocument(buf)
   166  		if errors.Is(err, io.EOF) {
   167  			return
   168  		}
   169  		if err != nil {
   170  			panic(err)
   171  		}
   172  		fmt.Println(doc.String())
   173  	}
   174  	// Output:
   175  	// {"x": {"$numberInt":"0"},"y": {"$numberInt":"1"}}
   176  	// {"x": {"$numberInt":"1"},"y": {"$numberInt":"2"}}
   177  	// {"x": {"$numberInt":"2"},"y": {"$numberInt":"3"}}
   178  	// {"x": {"$numberInt":"3"},"y": {"$numberInt":"4"}}
   179  	// {"x": {"$numberInt":"4"},"y": {"$numberInt":"5"}}
   180  }
   181  
   182  func ExampleEncoder_extendedJSON() {
   183  	// Create an Encoder that writes canonical Extended JSON values to a
   184  	// bytes.Buffer.
   185  	buf := new(bytes.Buffer)
   186  	vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
   187  	if err != nil {
   188  		panic(err)
   189  	}
   190  	encoder, err := bson.NewEncoder(vw)
   191  	if err != nil {
   192  		panic(err)
   193  	}
   194  
   195  	type Product struct {
   196  		Name  string `bson:"name"`
   197  		SKU   string `bson:"sku"`
   198  		Price int64  `bson:"price_cents"`
   199  	}
   200  
   201  	// Use the Encoder to marshal a BSON document that contains the name, SKU,
   202  	// and price (in cents) of a product.
   203  	product := Product{
   204  		Name:  "Cereal Rounds",
   205  		SKU:   "AB12345",
   206  		Price: 399,
   207  	}
   208  	err = encoder.Encode(product)
   209  	if err != nil {
   210  		panic(err)
   211  	}
   212  
   213  	fmt.Println(buf.String())
   214  	// Output: {"name":"Cereal Rounds","sku":"AB12345","price_cents":{"$numberLong":"399"}}
   215  }
   216  
   217  func ExampleEncoder_multipleExtendedJSONDocuments() {
   218  	// Create an Encoder that writes canonical Extended JSON values to a
   219  	// bytes.Buffer.
   220  	buf := new(bytes.Buffer)
   221  	vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
   222  	if err != nil {
   223  		panic(err)
   224  	}
   225  	encoder, err := bson.NewEncoder(vw)
   226  	if err != nil {
   227  		panic(err)
   228  	}
   229  
   230  	type Coordinate struct {
   231  		X int
   232  		Y int
   233  	}
   234  
   235  	// Use the encoder to marshal 5 Coordinate values as a sequence of Extended
   236  	// JSON documents.
   237  	for i := 0; i < 5; i++ {
   238  		err := encoder.Encode(Coordinate{
   239  			X: i,
   240  			Y: i + 1,
   241  		})
   242  		if err != nil {
   243  			panic(err)
   244  		}
   245  	}
   246  
   247  	fmt.Println(buf.String())
   248  	// Output:
   249  	// {"x":{"$numberInt":"0"},"y":{"$numberInt":"1"}}
   250  	// {"x":{"$numberInt":"1"},"y":{"$numberInt":"2"}}
   251  	// {"x":{"$numberInt":"2"},"y":{"$numberInt":"3"}}
   252  	// {"x":{"$numberInt":"3"},"y":{"$numberInt":"4"}}
   253  	// {"x":{"$numberInt":"4"},"y":{"$numberInt":"5"}}
   254  }
   255  
   256  func ExampleEncoder_IntMinSize() {
   257  	// Create an encoder that will marshal integers as the minimum BSON int size
   258  	// (either 32 or 64 bits) that can represent the integer value.
   259  	type foo struct {
   260  		Bar uint32
   261  	}
   262  
   263  	buf := new(bytes.Buffer)
   264  	vw, err := bsonrw.NewBSONValueWriter(buf)
   265  	if err != nil {
   266  		panic(err)
   267  	}
   268  
   269  	enc, err := bson.NewEncoder(vw)
   270  	if err != nil {
   271  		panic(err)
   272  	}
   273  
   274  	enc.IntMinSize()
   275  
   276  	err = enc.Encode(foo{2})
   277  	if err != nil {
   278  		panic(err)
   279  	}
   280  
   281  	fmt.Println(bson.Raw(buf.Bytes()).String())
   282  	// Output:
   283  	// {"bar": {"$numberInt":"2"}}
   284  }
   285  

View as plain text