1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
// Copyright (C) MongoDB, Inc. 2023-present.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package bson_test
import (
"bytes"
"errors"
"fmt"
"io"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsonrw"
)
func ExampleDecoder() {
// 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, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
if err != nil {
panic(err)
}
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}
}
func ExampleDecoder_DefaultDocumentM() {
// 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, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
if err != nil {
panic(err)
}
type City struct {
Name string `bson:"name"`
Properties interface{} `bson:"properties"`
}
// Configure the Decoder to default to decoding BSON documents as the bson.M
// type if the decode destination has no type information. The Properties
// field in the City struct will be decoded as a "bson.M" (i.e. map) instead
// of the default "bson.D".
decoder.DefaultDocumentM()
var res City
err = decoder.Decode(&res)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", res)
// Output: {Name:New York Properties:map[elevation:10 population:8804190 state:NY]}
}
func ExampleDecoder_UseJSONStructTags() {
// 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, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
if err != nil {
panic(err)
}
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 ExampleDecoder_extendedJSON() {
// 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 := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
if err != nil {
panic(err)
}
decoder, err := bson.NewDecoder(vr)
if err != nil {
panic(err)
}
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}
}
func ExampleDecoder_multipleExtendedJSONDocuments() {
// 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 := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
if err != nil {
panic(err)
}
decoder, err := bson.NewDecoder(vr)
if err != nil {
panic(err)
}
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}
}
|