• Stars
    star
    368
  • Rank 111,794 (Top 3 %)
  • Language
    Rust
  • License
    MIT License
  • Created about 9 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Encoding and decoding support for BSON in Rust

bson

crates.io docs.rs crates.io

Encoding and decoding support for BSON in Rust

Index

Useful links

Installation

Requirements

  • Rust 1.48+

Importing

This crate is available on crates.io. To use it in your application, simply add it to your project's Cargo.toml.

[dependencies]
bson = "2.10.0"

Note that if you are using bson through the mongodb crate, you do not need to specify it in your Cargo.toml, since the mongodb crate already re-exports it.

Feature Flags

Feature Description Extra dependencies Default
chrono-0_4 Enable support for v0.4 of the chrono crate in the public API. n/a no
uuid-0_8 Enable support for v0.8 of the uuid crate in the public API. n/a no
uuid-1 Enable support for v1.x of the uuid crate in the public API. n/a no
serde_with Enable serde_with 1.x integrations for bson::DateTime and bson::Uuid. serde_with no
serde_with-3 Enable serde_with 3.x integrations for bson::DateTime and bson::Uuid. serde_with no

Overview of the BSON Format

BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a datetime type and a binary data type.

// JSON equivalent
{"hello": "world"}

// BSON encoding
\x16\x00\x00\x00                   // total document size
\x02                               // 0x02 = type String
hello\x00                          // field name
\x06\x00\x00\x00world\x00          // field value
\x00                               // 0x00 = type EOO ('end of object')

BSON is the primary data representation for MongoDB, and this crate is used in the mongodb driver crate in its API and implementation.

For more information about BSON itself, see bsonspec.org.

Usage

BSON values

Many different types can be represented as a BSON value, including 32-bit and 64-bit signed integers, 64 bit floating point numbers, strings, datetimes, embedded documents, and more. To see a full list of possible BSON values, see the BSON specification. The various possible BSON values are modeled in this crate by the Bson enum.

Creating Bson instances

Bson values can be instantiated directly or via the bson! macro:

let string = Bson::String("hello world".to_string());
let int = Bson::Int32(5);
let array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);

let string: Bson = "hello world".into();
let int: Bson = 5i32.into();

let string = bson!("hello world");
let int = bson!(5);
let array = bson!([5, false]);

bson! supports both array and object literals, and it automatically converts any values specified to Bson, provided they are Into<Bson>.

Bson value unwrapping

Bson has a number of helper methods for accessing the underlying native Rust types. These helpers can be useful in circumstances in which the specific type of a BSON value is known ahead of time.

e.g.:

let value = Bson::Int32(5);
let int = value.as_i32(); // Some(5)
let bool = value.as_bool(); // None

let value = bson!([true]);
let array = value.as_array(); // Some(&Vec<Bson>)

BSON documents

BSON documents are ordered maps of UTF-8 encoded strings to BSON values. They are logically similar to JSON objects in that they can contain subdocuments, arrays, and values of several different types. This crate models BSON documents via the Document struct.

Creating Documents

Documents can be created directly either from a byte reader containing BSON data or via the doc! macro:

let mut bytes = hex::decode("0C0000001069000100000000").unwrap();
let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); // { "i": 1 }

let doc = doc! {
   "hello": "world",
   "int": 5,
   "subdoc": { "cat": true },
};

doc! works similarly to bson!, except that it always returns a Document rather than a Bson.

Document member access

Document has a number of methods on it to facilitate member access:

let doc = doc! {
   "string": "string",
   "bool": true,
   "i32": 5,
   "doc": { "x": true },
};

// attempt get values as untyped Bson
let none = doc.get("asdfadsf"); // None
let value = doc.get("string"); // Some(&Bson::String("string"))

// attempt to get values with explicit typing
let string = doc.get_str("string"); // Ok("string")
let subdoc = doc.get_document("doc"); // Some(Document({ "x": true }))
let error = doc.get_i64("i32"); // Err(...)

Modeling BSON with strongly typed data structures

While it is possible to work with documents and BSON values directly, it will often introduce a lot of boilerplate for verifying the necessary keys are present and their values are the correct types. serde provides a powerful way of mapping BSON data into Rust data structures largely automatically, removing the need for all that boilerplate.

e.g.:

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: i32,
    phones: Vec<String>,
}

// Some BSON input data as a `Bson`.
let bson_data: Bson = bson!({
    "name": "John Doe",
    "age": 43,
    "phones": [
        "+44 1234567",
        "+44 2345678"
    ]
});

// Deserialize the Person struct from the BSON data, automatically
// verifying that the necessary keys are present and that they are of
// the correct types.
let mut person: Person = bson::from_bson(bson_data).unwrap();

// Do things just like with any other Rust data structure.
println!("Redacting {}'s record.", person.name);
person.name = "REDACTED".to_string();

// Get a serialized version of the input data as a `Bson`.
let redacted_bson = bson::to_bson(&person).unwrap();

Any types that implement Serialize and Deserialize can be used in this way. Doing so helps separate the "business logic" that operates over the data from the (de)serialization logic that translates the data to/from its serialized form. This can lead to more clear and concise code that is also less error prone.

Working with datetimes

The BSON format includes a datetime type, which is modeled in this crate by the bson::DateTime struct, and the Serialize and Deserialize implementations for this struct produce and parse BSON datetimes when serializing to or deserializing from BSON. The popular crate chrono also provides a DateTime type, but its Serialize and Deserialize implementations operate on strings instead, so when using it with BSON, the BSON datetime type is not used. To work around this, the chrono-0_4 feature flag can be enabled. This flag exposes a number of convenient conversions between bson::DateTime and chrono::DateTime, including the chrono_datetime_as_bson_datetime serde helper, which can be used to (de)serialize chrono::DateTimes to/from BSON datetimes, and the From<chrono::DateTime> implementation for Bson, which allows chrono::DateTime values to be used in the doc! and bson! macros.

e.g.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Foo {
    // serializes as a BSON datetime.
    date_time: bson::DateTime,

    // serializes as an RFC 3339 / ISO-8601 string.
    chrono_datetime: chrono::DateTime<chrono::Utc>,

    // serializes as a BSON datetime.
    // this requires the "chrono-0_4" feature flag
    #[serde(with = "bson::serde_helpers::chrono_datetime_as_bson_datetime")]
    chrono_as_bson: chrono::DateTime<chrono::Utc>,
}

// this automatic conversion also requires the "chrono-0_4" feature flag
let query = doc! {
    "created_at": chrono::Utc::now(),
};

Working with UUIDs

See the module-level documentation for the bson::uuid module.

WASM support

This crate compiles to the wasm32-unknown-unknown target; when doing so, the js-sys crate is used for the current timestamp component of ObjectId generation.

Minimum supported Rust version (MSRV)

The MSRV for this crate is currently 1.64.0. This will be rarely be increased, and if it ever is, it will only happen in a minor or major version release.

Contributing

We encourage and would happily accept contributions in the form of GitHub pull requests. Before opening one, be sure to run the tests locally; check out the testing section for information on how to do that. Once you open a pull request, your branch will be run against the same testing matrix that we use for our continuous integration system, so it is usually sufficient to only run the integration tests locally against a standalone. Remember to always run the linter tests before opening a pull request.

Running the tests

Integration and unit tests

To actually run the tests, you can use cargo like you would in any other crate:

cargo test --verbose # runs against localhost:27017

Linter Tests

Our linter tests use the nightly version of rustfmt to verify that the source is formatted properly and the stable version of clippy to statically detect any common mistakes. You can use rustup to install them both:

rustup component add clippy --toolchain stable
rustup component add rustfmt --toolchain nightly

To run the linter tests, run the check-clippy.sh and check-rustfmt.sh scripts in the .evergreen directory:

bash .evergreen/check-clippy.sh && bash .evergreen/check-rustfmt.sh

Continuous Integration

Commits to main are run automatically on evergreen.

More Repositories

1

mongo

The MongoDB Database
C++
25,403
star
2

node-mongodb-native

The official MongoDB Node.js driver
TypeScript
9,953
star
3

mongo-go-driver

The Official Golang driver for MongoDB
Go
7,927
star
4

laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)
PHP
6,932
star
5

mongo-python-driver

PyMongo - the Official MongoDB Python driver
Python
4,045
star
6

mongoid

The Official Ruby Object Mapper for MongoDB
Ruby
3,922
star
7

mongo-csharp-driver

The Official C# .NET Driver for MongoDB
C#
3,038
star
8

mongo-java-driver

The official MongoDB drivers for Java, Kotlin, and Scala
Java
2,568
star
9

motor

Motor - the async Python driver for MongoDB and Tornado or asyncio
Python
2,318
star
10

mongo-php-library

The Official MongoDB PHP library
PHP
1,568
star
11

mongo-hadoop

MongoDB Connector for Hadoop
Java
1,519
star
12

mongo-ruby-driver

The Official MongoDB Ruby Driver
Ruby
1,422
star
13

mongo-rust-driver

The official MongoDB Rust Driver
Rust
1,268
star
14

mongodb-kubernetes-operator

MongoDB Community Kubernetes Operator
Go
1,136
star
15

mongo-php-driver-legacy

Legacy MongoDB PHP driver
PHP
1,093
star
16

js-bson

BSON Parser for node and browser
TypeScript
1,085
star
17

mongo-cxx-driver

C++ Driver for MongoDB
C++
1,005
star
18

mongo-tools

Go
971
star
19

homebrew-brew

The Official MongoDB Software Homebrew Tap
Ruby
901
star
20

mongo-php-driver

The Official MongoDB PHP driver
PHP
838
star
21

mongo-c-driver

The Official MongoDB driver for C language
C
794
star
22

docs

The MongoDB Documentation Project Source.
Java
726
star
23

mongo-spark

The MongoDB Spark Connector
Java
700
star
24

casbah

Casbah is now officially end-of-life (EOL).
Scala
514
star
25

mongo-snippets

snippets of code that might be useful for your mongodb deployment
C++
381
star
26

specifications

Specifications related to MongoDB
Python
375
star
27

cookbook

MongoDB recipes.
Ruby
354
star
28

pymodm

A Pythonic, object-oriented interface for working with MongoDB.
Python
351
star
29

libbson

ARCHIVED - libbson has moved to https://github.com/mongodb/mongo-c-driver/tree/master/src/libbson
C
343
star
30

mongo-perf

performance tools for mongodb
JavaScript
340
star
31

mongo-swift-driver

The official MongoDB driver for Swift
Swift
325
star
32

mongo-kafka

MongoDB Kafka Connector
Java
321
star
33

mongodb-enterprise-kubernetes

MongoDB Enterprise Kubernetes Operator
Dockerfile
320
star
34

mongo-scala-driver

Scala
286
star
35

mongo-efcore-provider

MongoDB Entity Framework Core Provider
C#
257
star
36

terraform-provider-mongodbatlas

Terraform MongoDB Atlas Provider: Deploy, update, and manage MongoDB Atlas infrastructure as code through HashiCorp Terraform
Go
224
star
37

leafygreen-ui

LeafyGreen UI – LeafyGreen's React UI Kit
TypeScript
206
star
38

mongodb-atlas-cli

MongoDB Atlas CLI and MongoDB CLI enable you to manage your MongoDB in the Cloud
Go
152
star
39

stitch-examples

MongoDB Stitch Examples
Java
138
star
40

mongodb-atlas-kubernetes

MongoDB Atlas Kubernetes Operator - Manage your MongoDB Atlas clusters from Kubernetes
Go
130
star
41

support-tools

For support tools to be shared publicly
Go
119
star
42

stitch-js-sdk

MongoDB Stitch JavaScript SDK
TypeScript
113
star
43

mongo-bi-connector-odbc-driver

ODBC driver for MongoDB Connector for Business Intelligence
C
106
star
44

mongo-azure

C#
103
star
45

amboy

Amboy -- A Go(lang) Job Queue Tool
Go
91
star
46

bsonspec.org

site for bsonspec.org
HTML
89
star
47

libmongocrypt

Required C library for Client Side and Queryable Encryption in MongoDB
C
87
star
48

terraform-aws-ecs-task-definition

A Terraform module for creating Amazon ECS Task Definitions
HCL
84
star
49

chatbot

MongoDB Chatbot Framework. Powered by MongoDB and Atlas Vector Search.
TypeScript
82
star
50

helm-charts

Smarty
80
star
51

go-client-mongodb-atlas

Go Client for MongoDB Atlas
Go
77
star
52

bson-ruby

Ruby Implementation of the BSON Specification (2.0.0+)
Ruby
77
star
53

docs-ecosystem

MongoDB Ecosystem Documentation
Python
76
star
54

mongo-java-driver-reactivestreams

The Java Reactive Stream driver for MongoDB
Java
73
star
55

stitch-android-sdk

MongoDB Stitch Android SDK
Java
57
star
56

mongodbatlas-cloudformation-resources

MongoDB Atlas CloudFormation Resources: Deploy, update, and manage MongoDB Atlas infrastructure as code through AWS CloudFormation
Go
54
star
57

winkerberos

A native Kerberos client implementation for Python on Windows
C
47
star
58

genny

🧞‍♀️ Grants 3 wishes. As long as those wishes are to generate load 🧞‍♂️
C++
46
star
59

docs-realm

Realm Database SDK documentation
Kotlin
43
star
60

bson-numpy

This project has been superseded by PyMongoArrow - https://github.com/mongodb-labs/mongo-arrow/tree/main/bindings/python
C
43
star
61

docs-tools

Common tools and content for MongoDB documentation projects.
Python
42
star
62

stitch-ios-sdk

Swift
42
star
63

swift-bson

pure Swift BSON library
Swift
41
star
64

signal-processing-algorithms

Python
38
star
65

mongo-hhvm-driver

MongoDB HHVM driver **Note, this driver is no longer maintained**
PHP
35
star
66

mongodb-vapor

MongoDB + Vapor integration
Swift
34
star
67

atlas-billing

JavaScript
33
star
68

design

Source code for MongoDB.design, LeafyGreen's official documentation site.
TypeScript
33
star
69

awscdk-resources-mongodbatlas

MongoDB Atlas AWS CDK Resources
TypeScript
31
star
70

mongo-jdbc-driver

JDBC Driver for MongoDB Atlas SQL interface
Java
31
star
71

mongo-java-driver-rx

The MongoDB Java RX driver is now officially end-of-life (EOL)
Java
30
star
72

atlas-app-services-examples

Example use cases for Atlas App Services
JavaScript
30
star
73

snooty

MongoDB Documentation front end
JavaScript
28
star
74

charts-embedding-examples

charts-embedding-examples
HTML
23
star
75

mongo-csharp-driver-jsondotnet

The C#/.NET driver will have a new component to integrate with JSON.NET that needs to live separately from the .NET driver itself.
C#
22
star
76

realm-practice

realm-node-practice & realm-swift-practice
Swift
22
star
77

mongo-csharp-analyzer

The MongoDB Analyzer is a free tool that helps you understand how your code translates into the MongoDB Query API.
C#
22
star
78

ftdc

utils for working with mongodb full-time diagnostic data capture files
Go
20
star
79

mongo-qa

General QA materials for Mongo
Java
19
star
80

curator

Curator -- a build and package automation tool
Go
19
star
81

anser

Data Transformation/Migration Tool
Go
19
star
82

marian

A search engine focused on documentation.
JavaScript
18
star
83

snooty-parser

Python
18
star
84

template-app-react-native-todo

Atlas Template Starter App - Use Device Sync from a React Native client application. This repo is generated from source code in https://github.com/mongodb-university/realm-template-apps
TypeScript
18
star
85

terraform-provider-mongodbatlas-archive

ARCHIVED ---- Hashicorp Terraform Provider for MongoDB Atlas - please use https://github.com/terraform-providers/terraform-provider-mongodbatlas
Go
17
star
86

docs-bi-connector

Makefile
16
star
87

kbson

Kotlin Multiplatform Bson Library
Kotlin
16
star
88

docs-compass

Python
16
star
89

academia-mongodb-lab-python

Lab using MongoDB with Python (PyMongo driver). Created for educational use by the MongoDB for Academia program.
Jupyter Notebook
16
star
90

mongo-odbc-driver

Rust
15
star
91

grip

Go
15
star
92

vault-plugin-secrets-mongodbatlas

ARCHIVED - Hashicorp Vault MongoDB Atlas Secrets Engine - Now hosted at https://github.com/hashicorp/vault-plugin-secrets-mongodbatlas/
Go
15
star
93

hacktoberfest2018

Hacktoberfest Repository for MongoDB
JavaScript
14
star
94

mongodb-atlas-service-broker

Implementation of the Open Service Broker API for MongoDB Atlas. Deploy this service to easily manage Atlas instances!
Go
14
star
95

snooty-vscode

TypeScript
14
star
96

docs-worker-pool

TypeScript
13
star
97

mongo-meta-driver

Ruby
13
star
98

docs-java

MongoDB Java driver documentation
Java
13
star
99

mongo-tools-common

Go
13
star
100

jasper

Jasper is a Process Management Framework
Go
13
star