bson/lib.rs
1// The MIT License (MIT)
2
3// Copyright (c) 2015 Y. T. Chung <zonyitoo@gmail.com>
4
5// Permission is hereby granted, free of charge, to any person obtaining a copy of
6// this software and associated documentation files (the "Software"), to deal in
7// the Software without restriction, including without limitation the rights to
8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software is furnished to do so,
10// subject to the following conditions:
11
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22//! BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents.
23//! Like JSON, BSON supports the embedding of documents and arrays within other documents
24//! and arrays. BSON also contains extensions that allow representation of data types that
25//! are not part of the JSON spec. For example, BSON has a datetime type and a binary data type.
26//!
27//! ```text
28//! // JSON equivalent
29//! {"hello": "world"}
30//!
31//! // BSON encoding
32//! \x16\x00\x00\x00 // total document size
33//! \x02 // 0x02 = type String
34//! hello\x00 // field name
35//! \x06\x00\x00\x00world\x00 // field value
36//! \x00 // 0x00 = type EOO ('end of object')
37//! ```
38//!
39//! BSON is the primary data representation for [MongoDB](https://www.mongodb.com/), and this crate is used in the
40//! [`mongodb`](https://docs.rs/mongodb/latest/mongodb/) driver crate in its API and implementation.
41//!
42//! For more information about BSON itself, see [bsonspec.org](http://bsonspec.org).
43//!
44//! ## Installation
45//! ### Requirements
46//! - Rust 1.64+
47//!
48//! ### Importing
49//! This crate is available on [crates.io](https://crates.io/crates/bson). To use it in your application,
50//! simply add it to your project's `Cargo.toml`.
51//!
52//! ```toml
53//! [dependencies]
54//! bson = "2.15.0"
55//! ```
56//!
57//! Note that if you are using `bson` through the `mongodb` crate, you do not need to specify it in
58//! your `Cargo.toml`, since the `mongodb` crate already re-exports it.
59//!
60//! #### Feature Flags
61//!
62//! | Feature | Description | Default |
63//! |:-------------|:-----------------------------------------------------------------------------------------------------|:--------|
64//! | `chrono-0_4` | Enable support for v0.4 of the [`chrono`](https://docs.rs/chrono/0.4) crate in the public API. | no |
65//! | `uuid-0_8` | Enable support for v0.8 of the [`uuid`](https://docs.rs/uuid/0.8) crate in the public API. | no |
66//! | `uuid-1` | Enable support for v1.x of the [`uuid`](https://docs.rs/uuid/1.x) crate in the public API. | no |
67//! | `time-0_3` | Enable support for v0.3 of the [`time`](https://docs.rs/time/0.3) crate in the public API. | no |
68//! | `serde_with` | Enable [`serde_with`](https://docs.rs/serde_with/1.x) 1.x integrations for [`DateTime`] and [`Uuid`]. | no |
69//! | `serde_with-3` | Enable [`serde_with`](https://docs.rs/serde_with/3.x) 3.x integrations for [`DateTime`] and [`Uuid`]. | no |
70//! | `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. | no |
71//!
72//! ## BSON values
73//!
74//! Many different types can be represented as a BSON value, including 32-bit and 64-bit signed
75//! integers, 64 bit floating point numbers, strings, datetimes, embedded documents, and more. To
76//! see a full list of possible BSON values, see the [BSON specification](http://bsonspec.org/spec.html). The various
77//! possible BSON values are modeled in this crate by the [`Bson`](enum.Bson.html) enum.
78//!
79//! ### Creating [`Bson`](enum.Bson.html) instances
80//!
81//! [`Bson`](enum.Bson.html) values can be instantiated directly or via the
82//! [`bson!`](macro.bson.html) macro:
83//!
84//! ```rust
85//! use bson::{bson, Bson};
86//!
87//! let string = Bson::String("hello world".to_string());
88//! let int = Bson::Int32(5);
89//! let array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);
90//!
91//! let string: Bson = "hello world".into();
92//! let int: Bson = 5i32.into();
93//!
94//! let string = bson!("hello world");
95//! let int = bson!(5);
96//! let array = bson!([5, false]);
97//! ```
98//! [`bson!`](macro.bson.html) has supports both array and object literals, and it automatically
99//! converts any values specified to [`Bson`](enum.Bson.html), provided they are `Into<Bson>`.
100//!
101//! ### [`Bson`](enum.Bson.html) value unwrapping
102//!
103//! [`Bson`](enum.Bson.html) has a number of helper methods for accessing the underlying native Rust
104//! types. These helpers can be useful in circumstances in which the specific type of a BSON value
105//! is known ahead of time.
106//!
107//! e.g.:
108//! ```rust
109//! use bson::{bson, Bson};
110//!
111//! let value = Bson::Int32(5);
112//! let int = value.as_i32(); // Some(5)
113//! let bool = value.as_bool(); // None
114//!
115//! let value = bson!([true]);
116//! let array = value.as_array(); // Some(&Vec<Bson>)
117//! ```
118//!
119//! ## BSON documents
120//!
121//! BSON documents are ordered maps of UTF-8 encoded strings to BSON values. They are logically
122//! similar to JSON objects in that they can contain subdocuments, arrays, and values of several
123//! different types. This crate models BSON documents via the
124//! [`Document`](document/struct.Document.html) struct.
125//!
126//! ### Creating [`Document`](document/struct.Document.html)s
127//!
128//! [`Document`](document/struct.Document.html)s can be created directly either from a byte
129//! reader containing BSON data or via the `doc!` macro:
130//! ```rust
131//! use bson::{doc, Document};
132//! use std::io::Read;
133//!
134//! let mut bytes = hex::decode("0C0000001069000100000000").unwrap();
135//! let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); // { "i": 1 }
136//!
137//! let doc = doc! {
138//! "hello": "world",
139//! "int": 5,
140//! "subdoc": { "cat": true },
141//! };
142//! ```
143//! [`doc!`](macro.doc.html) works similarly to [`bson!`](macro.bson.html), except that it always
144//! returns a [`Document`](document/struct.Document.html) rather than a [`Bson`](enum.Bson.html).
145//!
146//! ### [`Document`](document/struct.Document.html) member access
147//!
148//! [`Document`](document/struct.Document.html) has a number of methods on it to facilitate member
149//! access:
150//!
151//! ```rust
152//! use bson::doc;
153//!
154//! let doc = doc! {
155//! "string": "string",
156//! "bool": true,
157//! "i32": 5,
158//! "doc": { "x": true },
159//! };
160//!
161//! // attempt get values as untyped Bson
162//! let none = doc.get("asdfadsf"); // None
163//! let value = doc.get("string"); // Some(&Bson::String("string"))
164//!
165//! // attempt to get values with explicit typing
166//! let string = doc.get_str("string"); // Ok("string")
167//! let subdoc = doc.get_document("doc"); // Some(Document({ "x": true }))
168//! let error = doc.get_i64("i32"); // Err(...)
169//! ```
170//!
171//! ## Modeling BSON with strongly typed data structures
172//!
173//! While it is possible to work with documents and BSON values directly, it will often introduce a
174//! lot of boilerplate for verifying the necessary keys are present and their values are the correct
175//! types. [`serde`](https://serde.rs/) provides a powerful way of mapping BSON data into Rust data structures largely
176//! automatically, removing the need for all that boilerplate.
177//!
178//! e.g.:
179//! ```rust
180//! use serde::{Deserialize, Serialize};
181//! use bson::{bson, Bson};
182//!
183//! #[derive(Serialize, Deserialize)]
184//! struct Person {
185//! name: String,
186//! age: i32,
187//! phones: Vec<String>,
188//! }
189//!
190//! // Some BSON input data as a [`Bson`].
191//! let bson_data: Bson = bson!({
192//! "name": "John Doe",
193//! "age": 43,
194//! "phones": [
195//! "+44 1234567",
196//! "+44 2345678"
197//! ]
198//! });
199//!
200//! // Deserialize the Person struct from the BSON data, automatically
201//! // verifying that the necessary keys are present and that they are of
202//! // the correct types.
203//! let mut person: Person = bson::from_bson(bson_data).unwrap();
204//!
205//! // Do things just like with any other Rust data structure.
206//! println!("Redacting {}'s record.", person.name);
207//! person.name = "REDACTED".to_string();
208//!
209//! // Get a serialized version of the input data as a [`Bson`].
210//! let redacted_bson = bson::to_bson(&person).unwrap();
211//! ```
212//!
213//! Any types that implement [`Serialize`](serde::Serialize) and [`Deserialize`](serde::Deserialize)
214//! can be used in this way. Doing so helps separate the "business logic" that operates over the
215//! data from the (de)serialization logic that translates the data to/from its serialized form. This
216//! can lead to more clear and concise code that is also less error prone.
217//!
218//! When serializing values that cannot be represented in BSON, or deserialzing from BSON that does
219//! not match the format expected by the type, the default error will only report the specific field
220//! that failed. To aid debugging, enabling the `serde_path_to_error` feature will
221//! [augment errors](crate::de::Error::WithPath) with the full field path from root object to
222//! failing field. This feature does incur a small CPU and memory overhead during (de)serialization
223//! and should be enabled with care in performance-sensitive environments.
224//!
225//! ## Working with datetimes
226//!
227//! The BSON format includes a datetime type, which is modeled in this crate by the
228//! [`DateTime`] struct, and the
229//! [`Serialize`](serde::Serialize) and [`Deserialize`](serde::Deserialize) implementations for this
230//! struct produce and parse BSON datetimes when serializing to or deserializing from BSON. The
231//! popular crate [`chrono`](docs.rs/chrono) also provides a [`DateTime`] type, but its
232//! [`Serialize`](serde::Serialize) and [`Deserialize`](serde::Deserialize) implementations operate
233//! on strings instead, so when using it with BSON, the BSON datetime type is not used. To work
234//! around this, the `chrono-0_4` feature flag can be enabled. This flag exposes a number of
235//! convenient conversions between [`bson::DateTime`](crate::DateTime) and [`chrono::DateTime`],
236//! including the [`serde_helpers::chrono_datetime_as_bson_datetime`]
237//! serde helper, which can be used to (de)serialize [`chrono::DateTime`]s to/from BSON datetimes,
238//! and the `From<chrono::DateTime>` implementation for [`Bson`], which allows [`chrono::DateTime`]
239//! values to be used in the `doc!` and `bson!` macros.
240//!
241//! e.g.
242//! ``` rust
243//! # #[cfg(feature = "chrono-0_4")]
244//! # {
245//! use serde::{Serialize, Deserialize};
246//! use bson::doc;
247//!
248//! #[derive(Serialize, Deserialize)]
249//! struct Foo {
250//! // serializes as a BSON datetime.
251//! date_time: bson::DateTime,
252//!
253//! // serializes as an RFC 3339 / ISO-8601 string.
254//! chrono_datetime: chrono::DateTime<chrono::Utc>,
255//!
256//! // serializes as a BSON datetime.
257//! // this requires the "chrono-0_4" feature flag
258//! #[serde(with = "bson::serde_helpers::chrono_datetime_as_bson_datetime")]
259//! chrono_as_bson: chrono::DateTime<chrono::Utc>,
260//! }
261//!
262//! // this automatic conversion also requires the "chrono-0_4" feature flag
263//! let query = doc! {
264//! "created_at": chrono::Utc::now(),
265//! };
266//! # }
267//! ```
268//!
269//! ## Working with UUIDs
270//!
271//! See the module level documentation for the [`uuid`] module.
272//!
273//! ## WASM support
274//!
275//! This crate compiles to the `wasm32-unknown-unknown` target; when doing so, the `js-sys` crate is
276//! used for the current timestamp component of `ObjectId` generation.
277//!
278//! ## Minimum supported Rust version (MSRV)
279//!
280//! The MSRV for this crate is currently 1.81. This will be rarely be increased, and if it ever
281//! is, it will only happen in a minor or major version release.
282
283#![allow(clippy::cognitive_complexity, clippy::derive_partial_eq_without_eq)]
284#![doc(html_root_url = "https://docs.rs/bson/2.6.0")]
285#![cfg_attr(docsrs, feature(doc_cfg))]
286
287#[doc(inline)]
288pub use self::{
289 binary::Binary,
290 bson::{Array, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex, Timestamp},
291 datetime::DateTime,
292 de::{
293 from_bson,
294 from_bson_with_options,
295 from_document,
296 from_document_with_options,
297 from_reader,
298 from_slice,
299 Deserializer,
300 DeserializerOptions,
301 },
302 decimal128::Decimal128,
303 raw::{
304 RawArray,
305 RawArrayBuf,
306 RawBinaryRef,
307 RawBson,
308 RawBsonRef,
309 RawDbPointerRef,
310 RawDocument,
311 RawDocumentBuf,
312 RawJavaScriptCodeWithScope,
313 RawJavaScriptCodeWithScopeRef,
314 RawRegexRef,
315 },
316 ser::{
317 to_bson,
318 to_bson_with_options,
319 to_document,
320 to_document_with_options,
321 to_raw_document_buf,
322 to_vec,
323 Serializer,
324 SerializerOptions,
325 },
326 uuid::{Uuid, UuidRepresentation},
327};
328
329#[allow(deprecated)]
330pub use self::de::{from_reader_utf8_lossy, from_slice_utf8_lossy};
331
332#[macro_use]
333mod macros;
334mod base64;
335pub mod binary;
336mod bson;
337pub mod datetime;
338pub mod de;
339pub mod decimal128;
340pub mod document;
341pub mod extjson;
342pub mod oid;
343pub mod raw;
344pub mod ser;
345pub mod serde_helpers;
346pub mod spec;
347pub mod uuid;
348
349#[cfg(test)]
350mod tests;