{"id":13439245,"url":"https://github.com/mongodb/bson-rust","last_synced_at":"2025-05-13T22:12:48.693Z","repository":{"id":30078603,"uuid":"33628160","full_name":"mongodb/bson-rust","owner":"mongodb","description":"Encoding and decoding support for BSON in Rust","archived":false,"fork":false,"pushed_at":"2025-05-08T20:06:16.000Z","size":1087,"stargazers_count":433,"open_issues_count":18,"forks_count":143,"subscribers_count":22,"default_branch":"main","last_synced_at":"2025-05-08T21:23:00.166Z","etag":null,"topics":["bson","json","mongodb","rust","serialization"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mongodb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-04-08T19:39:04.000Z","updated_at":"2025-05-08T20:06:20.000Z","dependencies_parsed_at":"2023-09-28T02:29:41.781Z","dependency_job_id":"735c402b-2541-49dc-8fa4-ccbe85be5b25","html_url":"https://github.com/mongodb/bson-rust","commit_stats":{"total_commits":419,"total_committers":85,"mean_commits":4.929411764705883,"dds":0.8520286396181385,"last_synced_commit":"0fbdeeffd3e9d4d811d119e19a9657c43d644f37"},"previous_names":["zonyitoo/bson-rs"],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fbson-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fbson-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fbson-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fbson-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mongodb","download_url":"https://codeload.github.com/mongodb/bson-rust/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254036843,"owners_count":22003654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bson","json","mongodb","rust","serialization"],"created_at":"2024-07-31T03:01:12.327Z","updated_at":"2025-05-13T22:12:43.678Z","avatar_url":"https://github.com/mongodb.png","language":"Rust","readme":"# bson\n\n[![crates.io](https://img.shields.io/crates/v/bson.svg)](https://crates.io/crates/bson)\n[![docs.rs](https://docs.rs/mongodb/badge.svg)](https://docs.rs/bson)\n[![crates.io](https://img.shields.io/crates/l/bson.svg)](https://crates.io/crates/bson)\n\nEncoding and decoding support for BSON in Rust\n\n## Index\n- [Installation](#installation)\n    - [Requirements](#requirements)\n    - [Importing](#importing)\n        - [Feature flags](#feature-flags)\n- [Useful links](#useful-links)\n- [Overview of BSON Format](#overview-of-the-bson-format)\n- [Usage](#usage)\n    - [BSON Values](#bson-values)\n    - [BSON Documents](#bson-documents)\n    - [Modeling BSON with strongly typed data structures](#modeling-bson-with-strongly-typed-data-structures)\n    - [Working with datetimes](#working-with-datetimes)\n    - [Working with UUIDs](#working-with-uuids)\n    - [WASM support](#wasm-support)\n- [Contributing](#contributing)\n- [Running the Tests](#running-the-tests)\n- [Continuous Integration](#continuous-integration)\n\n## Useful links\n- [API Documentation](https://docs.rs/bson/)\n- [Serde Documentation](https://serde.rs/)\n\n## Installation\n### Requirements\n- Rust 1.48+\n\n### Importing\nThis crate is available on [crates.io](https://crates.io/crates/bson). To use it in your application, simply add it to your project's `Cargo.toml`.\n\n```toml\n[dependencies]\nbson = \"2.14.0\"\n```\n\nNote that if you are using `bson` through the `mongodb` crate, you do not need to specify it in your\n`Cargo.toml`, since the `mongodb` crate already re-exports it.\n\n#### Feature Flags\n\n| Feature      | Description                                                                                                 | Extra dependencies | Default |\n| :----------- | :---------------------------------------------------------------------------------------------------------- | :----------------- | :------ |\n| `chrono-0_4` | Enable support for v0.4 of the [`chrono`](https://docs.rs/chrono/0.4) crate in the public API.              | n/a                | no      |\n| `uuid-0_8`   | Enable support for v0.8 of the [`uuid`](https://docs.rs/uuid/0.8) crate in the public API.                  | n/a                | no      |\n| `uuid-1`     | Enable support for v1.x of the [`uuid`](https://docs.rs/uuid/1.0) crate in the public API.                  | n/a                | no      |\n| `time-0_3`   | Enable support for v0.3 of the [`time`](https://docs.rs/time/0.3) crate in the public API.                  | n/a                | no      |\n| `serde_with` | Enable [`serde_with`](https://docs.rs/serde_with/1.x) 1.x integrations for `bson::DateTime` and `bson::Uuid`.| serde_with         | no      |\n| `serde_with-3` | Enable [`serde_with`](https://docs.rs/serde_with/3.x) 3.x integrations for `bson::DateTime` and `bson::Uuid`.| serde_with         | no      |\n| `serde_path_to_error` | Enable support for error paths via integration with [`serde_path_to_error`](https://docs.rs/serde_path_to_err/latest).  This is an unstable feature and any breaking changes to `serde_path_to_error` may affect usage of it via this feature.  | serde_path_to_error  | no |\n| `hashable`   | Implement `core::hash::Hash` and `std::cmp::Eq` on `Bson` and `Document`.                  | n/a                | no      |\n\n## Overview of the BSON Format\n\nBSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents.\nLike JSON, BSON supports the embedding of documents and arrays within other documents\nand arrays. BSON also contains extensions that allow representation of data types that\nare not part of the JSON spec. For example, BSON has a datetime type and a binary data type.\n\n```text\n// JSON equivalent\n{\"hello\": \"world\"}\n\n// BSON encoding\n\\x16\\x00\\x00\\x00                   // total document size\n\\x02                               // 0x02 = type String\nhello\\x00                          // field name\n\\x06\\x00\\x00\\x00world\\x00          // field value\n\\x00                               // 0x00 = type EOO ('end of object')\n```\n\nBSON is the primary data representation for [MongoDB](https://www.mongodb.com/), and this crate is used in the\n[`mongodb`](https://docs.rs/mongodb/latest/mongodb/) driver crate in its API and implementation.\n\nFor more information about BSON itself, see [bsonspec.org](http://bsonspec.org).\n\n## Usage\n\n### BSON values\n\nMany different types can be represented as a BSON value, including 32-bit and 64-bit signed\nintegers, 64 bit floating point numbers, strings, datetimes, embedded documents, and more. To\nsee a full list of possible BSON values, see the [BSON specification](http://bsonspec.org/spec.html). The various\npossible BSON values are modeled in this crate by the [`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html) enum.\n\n#### Creating [`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html) instances\n\n[`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html) values can be instantiated directly or via the\n[`bson!`](https://docs.rs/bson/latest/bson/macro.bson.html) macro:\n\n```rust\nlet string = Bson::String(\"hello world\".to_string());\nlet int = Bson::Int32(5);\nlet array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);\n\nlet string: Bson = \"hello world\".into();\nlet int: Bson = 5i32.into();\n\nlet string = bson!(\"hello world\");\nlet int = bson!(5);\nlet array = bson!([5, false]);\n```\n[`bson!`](https://docs.rs/bson/latest/bson/macro.bson.html) supports both array and object literals, and it automatically converts any values specified to [`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html), provided they are `Into\u003cBson\u003e`.\n\n#### [`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html) value unwrapping\n\n[`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html) 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\nis known ahead of time.\n\ne.g.:\n```rust\nlet value = Bson::Int32(5);\nlet int = value.as_i32(); // Some(5)\nlet bool = value.as_bool(); // None\n\nlet value = bson!([true]);\nlet array = value.as_array(); // Some(\u0026Vec\u003cBson\u003e)\n```\n\n### BSON documents\n\nBSON 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\n[`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html) struct.\n\n#### Creating [`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html)s\n\n[`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html)s can be created directly either from a byte\nreader containing BSON data or via the `doc!` macro:\n```rust\nlet mut bytes = hex::decode(\"0C0000001069000100000000\").unwrap();\nlet doc = Document::from_reader(\u0026mut bytes.as_slice()).unwrap(); // { \"i\": 1 }\n\nlet doc = doc! {\n   \"hello\": \"world\",\n   \"int\": 5,\n   \"subdoc\": { \"cat\": true },\n};\n```\n[`doc!`](https://docs.rs/bson/latest/bson/macro.doc.html) works similarly to [`bson!`](https://docs.rs/bson/latest/bson/macro.bson.html), except that it always\nreturns a [`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html) rather than a [`Bson`](https://docs.rs/bson/latest/bson/enum.Bson.html).\n\n#### [`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html) member access\n\n[`Document`](https://docs.rs/bson/latest/bson/document/struct.Document.html) has a number of methods on it to facilitate member\naccess:\n\n```rust\nlet doc = doc! {\n   \"string\": \"string\",\n   \"bool\": true,\n   \"i32\": 5,\n   \"doc\": { \"x\": true },\n};\n\n// attempt get values as untyped Bson\nlet none = doc.get(\"asdfadsf\"); // None\nlet value = doc.get(\"string\"); // Some(\u0026Bson::String(\"string\"))\n\n// attempt to get values with explicit typing\nlet string = doc.get_str(\"string\"); // Ok(\"string\")\nlet subdoc = doc.get_document(\"doc\"); // Some(Document({ \"x\": true }))\nlet error = doc.get_i64(\"i32\"); // Err(...)\n```\n\n### Modeling BSON with strongly typed data structures\n\nWhile it is possible to work with documents and BSON values directly, it will often introduce a\nlot of boilerplate for verifying the necessary keys are present and their values are the correct\ntypes. [`serde`](https://serde.rs/) provides a powerful way of mapping BSON data into Rust data structures largely\nautomatically, removing the need for all that boilerplate.\n\ne.g.:\n```rust\n#[derive(Serialize, Deserialize)]\nstruct Person {\n    name: String,\n    age: i32,\n    phones: Vec\u003cString\u003e,\n}\n\n// Some BSON input data as a `Bson`.\nlet bson_data: Bson = bson!({\n    \"name\": \"John Doe\",\n    \"age\": 43,\n    \"phones\": [\n        \"+44 1234567\",\n        \"+44 2345678\"\n    ]\n});\n\n// Deserialize the Person struct from the BSON data, automatically\n// verifying that the necessary keys are present and that they are of\n// the correct types.\nlet mut person: Person = bson::from_bson(bson_data).unwrap();\n\n// Do things just like with any other Rust data structure.\nprintln!(\"Redacting {}'s record.\", person.name);\nperson.name = \"REDACTED\".to_string();\n\n// Get a serialized version of the input data as a `Bson`.\nlet redacted_bson = bson::to_bson(\u0026person).unwrap();\n```\n\nAny types that implement `Serialize` and `Deserialize` can be used in this way. Doing so helps\nseparate the \"business logic\" that operates over the data from the (de)serialization logic that\ntranslates the data to/from its serialized form. This can lead to more clear and concise code\nthat is also less error prone.\n\nWhen serializing values that cannot be represented in BSON, or deserialzing from BSON that does\nnot match the format expected by the type, the default error will only report the specific field\nthat failed. To aid debugging, enabling the [`serde_path_to_error`](#feature-flags) feature will\n[augment errors](https://docs.rs/bson/latest/bson/de/enum.Error.html#variant.WithPath) with the\nfull field path from root object to failing field.  This feature does incur a small CPU and memory\noverhead during (de)serialization and should be enabled with care in performance-sensitive\nenvironments.\n\n### Working with datetimes\n\nThe BSON format includes a datetime type, which is modeled in this crate by the\n[`bson::DateTime`](https://docs.rs/bson/latest/bson/struct.DateTime.html) struct, and the\n`Serialize` and `Deserialize` implementations for this struct produce and parse BSON datetimes when\nserializing to or deserializing from BSON. The popular crate [`chrono`](https://docs.rs/chrono) also\nprovides a `DateTime` type, but its `Serialize` and `Deserialize` implementations operate on strings\ninstead, so when using it with BSON, the BSON datetime type is not used. To work around this, the\n`chrono-0_4` feature flag can be enabled. This flag exposes a number of convenient conversions\nbetween `bson::DateTime` and `chrono::DateTime`, including the\n[`chrono_datetime_as_bson_datetime`](https://docs.rs/bson/latest/bson/serde_helpers/chrono_datetime_as_bson_datetime/index.html)\nserde helper, which can be used to (de)serialize `chrono::DateTime`s to/from BSON datetimes, and the\n`From\u003cchrono::DateTime\u003e` implementation for `Bson`, which allows `chrono::DateTime` values to be\nused in the `doc!` and `bson!` macros.\n\ne.g.\n``` rust\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nstruct Foo {\n    // serializes as a BSON datetime.\n    date_time: bson::DateTime,\n\n    // serializes as an RFC 3339 / ISO-8601 string.\n    chrono_datetime: chrono::DateTime\u003cchrono::Utc\u003e,\n\n    // serializes as a BSON datetime.\n    // this requires the \"chrono-0_4\" feature flag\n    #[serde(with = \"bson::serde_helpers::chrono_datetime_as_bson_datetime\")]\n    chrono_as_bson: chrono::DateTime\u003cchrono::Utc\u003e,\n}\n\n// this automatic conversion also requires the \"chrono-0_4\" feature flag\nlet query = doc! {\n    \"created_at\": chrono::Utc::now(),\n};\n```\n\n### Working with UUIDs\n\nSee the module-level documentation for the [`bson::uuid` module](https://docs.rs/bson/latest/bson/uuid).\n\n### WASM support\n\nThis 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.\n\n## Minimum supported Rust version (MSRV)\n\nThe 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.\n\n## Contributing\n\nWe 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](#running-the-tests) 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](#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.\n\n## Running the tests\n\n### Integration and unit tests\n\nTo actually run the tests, you can use `cargo` like you would in any other crate:\n```bash\ncargo test --verbose # runs against localhost:27017\n```\n\n### Linter Tests\nOur 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.\nYou can use `rustup` to install them both:\n```bash\nrustup component add clippy --toolchain stable\nrustup component add rustfmt --toolchain nightly\n```\nTo run the linter tests, run the `check-clippy.sh` and `check-rustfmt.sh` scripts in the `.evergreen` directory:\n```bash\nbash .evergreen/check-clippy.sh \u0026\u0026 bash .evergreen/check-rustfmt.sh\n```\n\n## Continuous Integration\nCommits to main are run automatically on [evergreen](https://evergreen.mongodb.com/waterfall/rust-bson).\n","funding_links":[],"categories":["Libraries","库 Libraries"],"sub_categories":["Encoding","编码 Encoding"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongodb%2Fbson-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmongodb%2Fbson-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongodb%2Fbson-rust/lists"}