Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Encoding and decoding support for BSON in Rust

License

NotificationsYou must be signed in to change notification settings

mongodb/bson-rust

Repository files navigation

crates.iodocs.rscrates.io

Encoding and decoding support for BSON in Rust

Index

Useful links

Installation

Requirements

  • Rust 1.81+

Importing

This crate is available oncrates.io. To use it in your application, simply add it to your project'sCargo.toml.

[dependencies]bson ="3.0.0"

Note that if you are usingbson through themongodb crate, you do not need to specify it in yourCargo.toml, since themongodb crate already re-exports it.

Feature Flags

FeatureDescriptionExtra dependenciesDefault
chrono-0_4Enable support for v0.4 of thechrono crate in the public API.n/ano
uuid-1Enable support for v1.x of theuuid crate in the public API.n/ano
time-0_3Enable support for v0.3 of thetime crate in the public API.n/ano
serde_with-3Enableserde_with 3.x integrations forbson::DateTime andbson::Uuid.serde_withno
serde_path_to_errorEnable support for error paths via integration withserde_path_to_error. This is an unstable feature and any breaking changes toserde_path_to_error may affect usage of it via this feature.serde_path_to_errorno
compat-3-0-0Required for future compatibility if default features are disabled.n/ano
large_datesIncrease the supported year range for somebson::DateTime utilities from +/-9,999 (inclusive) to +/-999,999 (inclusive). Note that enabling this feature can impact performance and introduce parsing ambiguities.n/ano
serde_json-1Enable support for v1.x of theserde_json crate in the public API.serde_jsonno

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 documentsand arrays. BSON also contains extensions that allow representation of data types thatare 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 Stringhello\x00                          // field name\x06\x00\x00\x00world\x00          // field value\x00                               // 0x00 = type EOO ('end of object')

BSON is the primary data representation forMongoDB, and this crate is used in themongodb driver crate in its API and implementation.

For more information about BSON itself, seebsonspec.org.

Usage

BSON values

Many different types can be represented as a BSON value, including 32-bit and 64-bit signedintegers, 64 bit floating point numbers, strings, datetimes, embedded documents, and more. Tosee a full list of possible BSON values, see theBSON specification. The variouspossible BSON values are modeled in this crate by theBson enum.

CreatingBson instances

Bson values can be instantiated directly or via thebson! 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 toBson, provided they areInto<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 valueis known ahead of time.

e.g.:

let value =Bson::Int32(5);let int = value.as_i32();// Some(5)let bool = value.as_bool();// Nonelet 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 theDocument struct.

CreatingDocuments

Documents can be created directly either from a bytereader containing BSON data or via thedoc! macro:

letmut 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 tobson!, except that it alwaysreturns aDocument rather than aBson.

Document member access

Document has a number of methods on it to facilitate memberaccess:

let doc =doc!{"string":"string","bool":true,"i32":5,"doc":{"x":true},};// attempt get values as untyped Bsonlet none = doc.get("asdfadsf");// Nonelet value = doc.get("string");// Some(&Bson::String("string"))// attempt to get values with explicit typinglet 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 alot of boilerplate for verifying the necessary keys are present and their values are the correcttypes.serde provides a powerful way of mapping BSON data into Rust data structures largelyautomatically, removing the need for all that boilerplate.

e.g.:

#[derive(Serialize,Deserialize)]structPerson{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.letmut 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 implementSerialize andDeserialize can be used in this way. Doing so helpsseparate the "business logic" that operates over the data from the (de)serialization logic thattranslates the data to/from its serialized form. This can lead to more clear and concise codethat is also less error prone.

When serializing values that cannot be represented in BSON, or deserialzing from BSON that doesnot match the format expected by the type, the default error will only report the specific fieldthat failed. To aid debugging, enabling theserde_path_to_error feature willaugment errors with thefull field path from root object to failing field. This feature does incur a small CPU and memoryoverhead during (de)serialization and should be enabled with care in performance-sensitiveenvironments.

Working with datetimes

The BSON format includes a datetime type, which is modeled in this crate by thebson::DateTime struct, and theSerialize andDeserialize implementations for this struct produce and parse BSON datetimes whenserializing to or deserializing from BSON. The popular cratechrono alsoprovides aDateTime type, but itsSerialize andDeserialize implementations operate on stringsinstead, so when using it with BSON, the BSON datetime type is not used. To work around this, thechrono-0_4 feature flag can be enabled. This flag exposes a number of convenient conversionsbetweenbson::DateTime andchrono::DateTime, including thedatetime::FromChrono04DateTimeserde helper, which can be used to (de)serializechrono::DateTimes to/from BSON datetimes, and theFrom<chrono::DateTime> implementation forBson, which allowschrono::DateTime values to beused in thedoc! andbson! macros.

e.g.

use serde::{Serialize,Deserialize};use serde_with::serde_as;#[serde_as]#[derive(Serialize,Deserialize)]structFoo{// 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_as(as ="bson::serde_helpers::datetime::FromChrono04DateTime")]chrono_as_bson: chrono::DateTime<chrono::Utc>,}// this automatic conversion also requires the "chrono-0_4" feature flaglet query =doc!{"created_at": chrono::Utc::now(),};

Working with UUIDs

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

WASM support

This crate compiles to thewasm32-unknown-unknown target; when doing so, thejs-sys crate is used for the current timestamp component ofObjectId generation.

Minimum supported Rust version (MSRV)

The MSRV for this crate is currently 1.81. Increases to the MSRV will only happen in a minor or major version release, and will be to a Rust version at least six months old.

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 thetesting 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 ourcontinuous 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 usecargo like you would in any other crate:

cargotest --verbose# runs against localhost:27017

Linter Tests

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

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

To run the linter tests, run thecheck-clippy.sh andcheck-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 onevergreen.


[8]ページ先頭

©2009-2025 Movatter.jp