bson2/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.48+
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.0.1"
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 | Extra dependencies | Default |
63//! |:-------------|:----------------------------------------------------------------------------------------------------|:-------------------|:--------|
64//! | `chrono-0_4` | Enable support for v0.4 of the [`chrono`](docs.rs/chrono/0.4) crate in the public API. | n/a | no |
65//! | `uuid-0_8` | Enable support for v0.8 of the [`uuid`](docs.rs/uuid/0.8) crate in the public API. | n/a | no |
66//! | `serde_with` | Enable [`serde_with`](docs.rs/serde_with/latest) integrations for `bson::DateTime` and `bson::Uuid` | serde_with | no |
67//!
68//! ## BSON values
69//!
70//! Many different types can be represented as a BSON value, including 32-bit and 64-bit signed
71//! integers, 64 bit floating point numbers, strings, datetimes, embedded documents, and more. To
72//! see a full list of possible BSON values, see the [BSON specification](http://bsonspec.org/spec.html). The various
73//! possible BSON values are modeled in this crate by the [`Bson`](enum.Bson.html) enum.
74//!
75//! ### Creating [`Bson`](enum.Bson.html) instances
76//!
77//! [`Bson`](enum.Bson.html) values can be instantiated directly or via the
78//! [`bson!`](macro.bson.html) macro:
79//!
80//! ```rust
81//! use bson::{bson, Bson};
82//!
83//! let string = Bson::String("hello world".to_string());
84//! let int = Bson::Int32(5);
85//! let array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);
86//!
87//! let string: Bson = "hello world".into();
88//! let int: Bson = 5i32.into();
89//!
90//! let string = bson!("hello world");
91//! let int = bson!(5);
92//! let array = bson!([5, false]);
93//! ```
94//! [`bson!`](macro.bson.html) has supports both array and object literals, and it automatically
95//! converts any values specified to [`Bson`](enum.Bson.html), provided they are `Into<Bson>`.
96//!
97//! ### [`Bson`](enum.Bson.html) value unwrapping
98//!
99//! [`Bson`](enum.Bson.html) has a number of helper methods for accessing the underlying native Rust
100//! types. These helpers can be useful in circumstances in which the specific type of a BSON value
101//! is known ahead of time.
102//!
103//! e.g.:
104//! ```rust
105//! use bson::{bson, Bson};
106//!
107//! let value = Bson::Int32(5);
108//! let int = value.as_i32(); // Some(5)
109//! let bool = value.as_bool(); // None
110//!
111//! let value = bson!([true]);
112//! let array = value.as_array(); // Some(&Vec<Bson>)
113//! ```
114//!
115//! ## BSON documents
116//!
117//! BSON documents are ordered maps of UTF-8 encoded strings to BSON values. They are logically
118//! similar to JSON objects in that they can contain subdocuments, arrays, and values of several
119//! different types. This crate models BSON documents via the
120//! [`Document`](document/struct.Document.html) struct.
121//!
122//! ### Creating [`Document`](document/struct.Document.html)s
123//!
124//! [`Document`](document/struct.Document.html)s can be created directly either from a byte
125//! reader containing BSON data or via the `doc!` macro:
126//! ```rust
127//! use bson::{doc, Document};
128//! use std::io::Read;
129//!
130//! let mut bytes = hex::decode("0C0000001069000100000000").unwrap();
131//! let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); // { "i": 1 }
132//!
133//! let doc = doc! {
134//! "hello": "world",
135//! "int": 5,
136//! "subdoc": { "cat": true },
137//! };
138//! ```
139//! [`doc!`](macro.doc.html) works similarly to [`bson!`](macro.bson.html), except that it always
140//! returns a [`Document`](document/struct.Document.html) rather than a [`Bson`](enum.Bson.html).
141//!
142//! ### [`Document`](document/struct.Document.html) member access
143//!
144//! [`Document`](document/struct.Document.html) has a number of methods on it to facilitate member
145//! access:
146//!
147//! ```rust
148//! use bson::doc;
149//!
150//! let doc = doc! {
151//! "string": "string",
152//! "bool": true,
153//! "i32": 5,
154//! "doc": { "x": true },
155//! };
156//!
157//! // attempt get values as untyped Bson
158//! let none = doc.get("asdfadsf"); // None
159//! let value = doc.get("string"); // Some(&Bson::String("string"))
160//!
161//! // attempt to get values with explicit typing
162//! let string = doc.get_str("string"); // Ok("string")
163//! let subdoc = doc.get_document("doc"); // Some(Document({ "x": true }))
164//! let error = doc.get_i64("i32"); // Err(...)
165//! ```
166//!
167//! ## Modeling BSON with strongly typed data structures
168//!
169//! While it is possible to work with documents and BSON values directly, it will often introduce a
170//! lot of boilerplate for verifying the necessary keys are present and their values are the correct
171//! types. [`serde`](https://serde.rs/) provides a powerful way of mapping BSON data into Rust data structures largely
172//! automatically, removing the need for all that boilerplate.
173//!
174//! e.g.:
175//! ```rust
176//! use serde::{Deserialize, Serialize};
177//! use bson::{bson, Bson};
178//!
179//! #[derive(Serialize, Deserialize)]
180//! struct Person {
181//! name: String,
182//! age: i32,
183//! phones: Vec<String>,
184//! }
185//!
186//! // Some BSON input data as a `Bson`.
187//! let bson_data: Bson = bson!({
188//! "name": "John Doe",
189//! "age": 43,
190//! "phones": [
191//! "+44 1234567",
192//! "+44 2345678"
193//! ]
194//! });
195//!
196//! // Deserialize the Person struct from the BSON data, automatically
197//! // verifying that the necessary keys are present and that they are of
198//! // the correct types.
199//! let mut person: Person = bson::from_bson(bson_data).unwrap();
200//!
201//! // Do things just like with any other Rust data structure.
202//! println!("Redacting {}'s record.", person.name);
203//! person.name = "REDACTED".to_string();
204//!
205//! // Get a serialized version of the input data as a `Bson`.
206//! let redacted_bson = bson::to_bson(&person).unwrap();
207//! ```
208//!
209//! Any types that implement `Serialize` and `Deserialize` can be used in this way. Doing so helps
210//! separate the "business logic" that operates over the data from the (de)serialization logic that
211//! translates the data to/from its serialized form. This can lead to more clear and concise code
212//! that is also less error prone.
213//!
214//! ## Working with datetimes
215//!
216//! The BSON format includes a datetime type, which is modeled in this crate by the
217//! [`DateTime`] struct, and the
218//! `Serialize` and `Deserialize` implementations for this struct produce and parse BSON datetimes
219//! when serializing to or deserializing from BSON. The popular crate [`chrono`](docs.rs/chrono)
220//! also provides a `DateTime` type, but its `Serialize` and `Deserialize` implementations operate
221//! on strings instead, so when using it with BSON, the BSON datetime type is not used. To work
222//! around this, the `chrono-0_4` feature flag can be enabled. This flag exposes a number of
223//! convenient conversions between `bson::DateTime` and `chrono::DateTime`, including the
224//! [`serde_helpers::chrono_datetime_as_bson_datetime`]
225//! serde helper, which can be used to (de)serialize `chrono::DateTime`s to/from BSON datetimes, and
226//! the `From<chrono::DateTime>` implementation for [`Bson`], which allows `chrono::DateTime` values
227//! to be used in the `doc!` and `bson!` macros.
228//!
229//! e.g.
230//! ``` rust
231//! # #[cfg(feature = "chrono-0_4")]
232//! # {
233//! use serde::{Serialize, Deserialize};
234//! use bson::doc;
235//!
236//! #[derive(Serialize, Deserialize)]
237//! struct Foo {
238//! // serializes as a BSON datetime.
239//! date_time: bson::DateTime,
240//!
241//! // serializes as an RFC 3339 / ISO-8601 string.
242//! chrono_datetime: chrono::DateTime<chrono::Utc>,
243//!
244//! // serializes as a BSON datetime.
245//! // this requires the "chrono-0_4" feature flag
246//! #[serde(with = "bson::serde_helpers::chrono_datetime_as_bson_datetime")]
247//! chrono_as_bson: chrono::DateTime<chrono::Utc>,
248//! }
249//!
250//! // this automatic conversion also requires the "chrono-0_4" feature flag
251//! let query = doc! {
252//! "created_at": chrono::Utc::now(),
253//! };
254//! # }
255//! ```
256//!
257//! ## Working with UUIDs
258//!
259//! See the module level documentation for the [`uuid`] module.
260//!
261//! ## Minimum supported Rust version (MSRV)
262//!
263//! The MSRV for this crate is currently 1.48.0. This will be rarely be increased, and if it ever is,
264//! it will only happen in a minor or major version release.
265
266#![allow(clippy::cognitive_complexity)]
267#![doc(html_root_url = "https://docs.rs/bson/2.0.1")]
268#![cfg_attr(docsrs, feature(doc_cfg))]
269
270#[doc(inline)]
271pub use self::{
272 bson::{Array, Binary, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex, Timestamp},
273 datetime::DateTime,
274 de::{
275 from_bson, from_bson_with_options, from_document, from_document_with_options, from_reader, from_reader_utf8_lossy,
276 from_slice, from_slice_utf8_lossy, Deserializer, DeserializerOptions,
277 },
278 decimal128::Decimal128,
279 raw::{
280 RawArray, RawBinary, RawBson, RawDbPointer, RawDocument, RawDocumentBuf, RawJavaScriptCodeWithScope,
281 RawRegex,
282 },
283 ser::{
284 to_bson, to_bson_with_options, to_document, to_document_with_options, to_vec, Serializer,
285 SerializerOptions,
286 },
287 uuid::{Uuid, UuidRepresentation},
288};
289
290#[macro_use]
291mod macros;
292mod bson;
293pub mod datetime;
294pub mod de;
295pub mod decimal128;
296pub mod document;
297pub mod extjson;
298pub mod oid;
299pub mod raw;
300pub mod ser;
301pub mod serde_helpers;
302pub mod spec;
303pub mod uuid;
304
305#[cfg(test)]
306mod tests;