File: decoder_example_test.go

package info (click to toggle)
golang-mongodb-mongo-driver 1.17.1%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 25,988 kB
  • sloc: perl: 533; ansic: 491; python: 432; sh: 327; makefile: 174
file content (219 lines) | stat: -rw-r--r-- 5,471 bytes parent folder | download
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}
}