241 lines
6.1 KiB
Go
241 lines
6.1 KiB
Go
// 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"
|
|
|
|
"gitea.psichedelico.com/go/bson"
|
|
)
|
|
|
|
func ExampleEncoder() {
|
|
// 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"}}
|
|
}
|
|
|
|
type CityState struct {
|
|
City string
|
|
State string
|
|
}
|
|
|
|
func (k CityState) String() string {
|
|
return fmt.Sprintf("%s, %s", k.City, k.State)
|
|
}
|
|
|
|
func ExampleEncoder_StringifyMapKeysWithFmt() {
|
|
// 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 ExampleEncoder_UseJSONStructTags() {
|
|
// 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"}}
|
|
}
|
|
|
|
func ExampleEncoder_multipleBSONDocuments() {
|
|
// 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"}}
|
|
}
|
|
|
|
func ExampleEncoder_extendedJSON() {
|
|
// 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"}}
|
|
}
|
|
|
|
func ExampleEncoder_multipleExtendedJSONDocuments() {
|
|
// 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 ExampleEncoder_IntMinSize() {
|
|
// 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"}}
|
|
}
|