v2.0.0
Description
The MongoDB Rust driver team is pleased to announce the v2.0.0
release of the bson
crate. This release is the culmination of several months of work, and it contains a number of new features, API improvements, and bug fixes. This release will be included in v2.0.0
of the driver. It is intended that this release will be very stable and that bson
will not have another major release for quite a long time.
Note that the new minimum supported Rust version (MSRV) is now 1.48.0.
Highlighted changes
The following sections detail some of the more important changes included in this release. For a full list of changes, see the Full Release Notes section below.
Ensure API meets the Rust API Guidelines (RUST-765)
There is a community maintained list of API guidelines that every stable Rust library is recommended to meet. The crate's existing API wasn't conforming to these guidelines exactly, so a number of improvements were made to ensure that it does. Here we highlight a few of the more important changes made in this effort.
Stabilize or eliminate public dependencies on unstable crates (C-STABLE, RUST-739)
bson
included types from a number of unstable (pre-1.0) dependencies in its public API, which presented a problem for the stability of the library itself. In an effort to ensure that bson
will no longer be subject to the semver breaks of unstable dependencies and can stay on 2.0 for the foreseeable future, the public dependencies on unstable types were removed altogether or gated behind feature flags.
Here are the notable changes made as part of that:
Bson::DateTime(chrono::DateTime<Utc>)
=>Bson::DateTime(bson::DateTime)
,struct Datetime(pub chrono::DateTime)
=>struct DateTime { /* private fields */ }
- Instead of directly including a
DateTime
fromchrono
(which is currently0.4
) in theBson
enum, the variant now wraps thebson::DateTime
newtype defined withinbson
, and that newtype also no longer wraps achrono::DateTime
. This way the dependency onchrono
can be updated to new semver breaking versions without having to updatebson
's major version. - To ease in the construction and usage of the newtype from
chrono::DateTime
, thechrono-0_4
feature flag can be enabled, which includes aFrom<chrono::DateTime>
implementation forbson::DateTime
and aFrom<bson::DateTime>
implementation forchrono::DateTime
, as well as some serde helpers.
- Instead of directly including a
Document::get_datetime
returns aValueAccessResult
of&bson::DateTime
instead of&chrono::DateTime
Bson::as_datetime
returns anOption
of&bson::DateTime
instead of&chrono::DateTime
ObjectId::timestamp
returns acrate::DateTime
instead ofchrono::DateTime
oid::Error
no longer wrapshex::FromHexError
(thehex
crate is0.4
), see below for details.- The
Uuid
serde helpers, as well asFrom<Uuid>
implementations forBson
andBinary
, are now gated behind theuuid-0_8
feature flag.
Accept impl AsRef<str>
in Document
methods (C-GENERIC, RUST-765)
The methods on Document
that accepted keys previously accepted them as &str
. They were updated to accept impl AsRef<str>
instead to allow other string-like types to be used for key lookup, such as String
.
Use more standard conversion constructors for ObjectId
(C-CONV-TRAITS, C-CTOR, RUST-789)
ObjectId previously had three constructors: new
, with_bytes
, and with_string
. The latter two were a bit inconsistent with the functions they performed and with similar constructors for related types in the Rust ecosystem. To remedy this, the constructors were updated to match uuid::Uuid
's constructor API:
ObjectId::with_bytes
=>const ObjectId::from_bytes
ObjectId::with_string
=>ObjectId::parse_str
Error naming improvements (C-WORD-ORDER, C-STABLE)
Some error variants were renamed or restructured to be clearer or more informative. A complete summary of the changes are as follows:
bson::de::Error
:IoError
=>Io
FromUtf8Error
=>InvalidUtf8String
SyntaxError
=> removed, consolidated intoDeserializationError
.InvalidTimestamp(i64)
=>InvalidDateTime { key: String, datetime: i64 }
bson::ser::Error
:IoError
=>Io
InvalidMapKeyType { key: Bson }
=>InvalidDocumentKey(Bson)
UnsupportedUnsignedType
=> removedUnsignedTypesValueExceededRange
=>UnsignedIntegerExceededRange(u64)
oid::Error
:ArgumentError
=> removedFromHexError
=> removed, replaced by the newInvalidHexStringCharacter
andInvalidHexStringLength
variants
Other miscellaneous changes
There were some other smaller breaking changes made as part of this as well:
- Ensure public structs are future proof by marking them as
non_exhaustive
(C-STRUCT-PRIVATE) document::DocumentIterator
anddocument::DocumentIntoIterator
renamed todocument::Iter
anddocument::IntoIter
(C-ITER-TY)
Enable the u2i
behavior by default (RUST-968)
In the 1.x version of bson
, unsigned integers could not be serialized to BSON by default, but the u2i
feature flag could be enabled to allow them to be serialized by automatically converting them to signed integers. After some investigation, it was determined that this u2i
behavior was more consistent with the behavior of BSON libraries in other languages with unsigned integers, so bson
now exhibits it by default, and the u2i
feature flag was removed.
Implement Clone
on all error types (RUST-738)
Previously many of the error types did not implement Clone
, partially because many of them wrapped std::io::Error
. Not implementing Clone
made these errors difficult to work with, since they needed to be wrapped in an Arc
or Rc
in order to be passed around without transferring ownership. To avoid that requirement, we implemented Clone
on all of the error types in bson
. For the errors that wrapped std::io::Error
, this required wrapping the wrapped std::io::Error
s in Arc
s.
Implement Copy
for ObjectId
(RUST-680)
Since ObjectId
is just a wrapper around a 12-byte array, it is cheap to copy and therefore ought to implement Copy
. As part of this, helpers on Document
and Bson
were updated to return owned ObjectId
s instead of references to them.
Thanks to @jcdyer for contributing this change!
Replace linked-hash-map
with indexmap
(RUST-283)
The dependency on the now unmaintained linked-hash-map
was replaced with the more up-to-date indexmap
. While this isn't a breaking change on its own, the Entry
API of Document
was updated to match both that of std::collections::HashMap
and indexmap
in a breaking way.
Replace compat::u2f
with serde helpers (RUST-756)
The compat::u2f
module has long existed to provide a way to serialize unsigned integers as BSON doubles, but it is inconsistent with the API we provide for these kinds of conversions today, namely the serde_helpers
functions and modules. In order to present a more consistent API, the compat::u2f
module was removed and most of its conversion helpers were rewritten as serde_helpers
.
Remove the decimal128
feature flag (RUST-960, #287)
It was determined that the BSON serialization format that was used when the experimental decimal128
feature flag was enabled did not match the format expected by the database or other MongoDB tools and drivers. Because of this, the feature flag has been removed, as there was no way to use it correctly. See #282 for more details.
If you were relying on this feature flag or are just interested in a complete decimal128 implementation, please let us know on #53.
Support for serialization to and deserialization from BSON bytes (RUST-870, RUST-871, #276, #279)
This release adds support for direct serialization to and deserialization from BSON bytes via bson::to_vec
and bson::from_slice
/ bson::from_reader
, eliminating the need to go through Document
when converting between Rust data types and BSON bytes. This can enable significant performance improvements in certain circumstances; most notably, this will greatly improve the performance of the MongoDB driver, which in 2.0.0
will begin leveraging this functionality.
Properly produce and ingest RFC 3339 (ISO 8601) datetimes in serde helpers (RUST-825)
The iso_string_as_bson_datetime
and bson_datetime_as_iso_string
serde helpers were not producing or only accepting valid ISO 8601 strings. This has been fixed, and the helpers have been renamed to rfc3339_string_as_bson_datetime
and bson_datetime_as_rfc3339_string
to more accurately reflect the standard they conform to.
Introduce serde helpers for legacy UUID formats (RUST-687)
The Python, Java, and C# drivers all used to serialize UUIDs with different legacy formats, none of which were supported by the existing UUID serde helper. To add support for serializing and deserializing these UUIDs, new serde helpers were introduced for each of the legacy formats. These helpers are also gated behind the "uuid-0_8"
feature flag.
Thanks to @kenkoooo for contributing this change!
Add pretty-printed Debug
implementation to BSON types (RUST-282)
BSON related types now support being pretty-printed via the {:#?}
format specifier.
e.g.
let doc = doc! {
"oid": ObjectId::new(),
"arr": Bson::Array(vec! [
Bson::Null,
Bson::Timestamp(Timestamp { time: 1, increment: 1 }),
]),
"doc": doc! { "a": 1, "b": "data"},
};
println!("{:#?}", doc);
Prints the following:
Document({
"oid": ObjectId(
"60d60c360026a43f00e47007",
),
"arr": Array([
Null,
Timestamp {
time: 1,
increment: 1,
},
]),
"doc": Document({
"a": Int32(
1,
),
"b": String(
"data",
),
}),
})
Implement From<Option<T>>
for Bson
where T: Into<Bson>
(RUST-806)
A blanket From<Option<T>>
implementation was added for T
that implement Into<Bson>
. If the value is Some(T)
, the T
is converted into Bson
using T
's Into
implementation, and if it's None
, it will be converted into Bson::Null
.
A nice benefit of this is that Option<T>
can now be used in the bson!
and doc!
macros directly:
let some: Option<i32> = Some(5);
let none: Option<i32> = None;
let doc = doc! {
"some": some,
"none": none,
};
println!("{}", doc);
Prints:
{ "some": 5, "none": null }
Full Release Notes
New Features
- RUST-687 Introduce serde helpers for legacy UUID formats (thanks @kenkoooo!)
- RUST-688 Support for borrowed deserialization (#276)
- RUST-870 Support deserializing directly from raw BSON (#276)
- RUST-871 Support serializing directly to BSON bytes (#279)
- RUST-680 Implement
Copy
forObjectId
(breaking) - RUST-747 Add serde helper to deserialize hex string from
ObjectId
(thanks @moka491!) - RUST-738 Implement
Clone
on BSON error types (breaking) - RUST-806 Implement
From<Option<T>>
forBson
whereT: Into<Bson>
- RUST-841 Mark
ObjectId::bytes
asconst
- RUST-868 Add
serialize_object_id_as_hex_string
serde helper - RUST-282 Add pretty-printed
Debug
implementation to BSON types
Improvements
- RUST-283 Replace
linked-hash-map
withindexmap
(breaking) - RUST-711 Use
imports_granularity=Crate
in rustfmt config - RUST-756 Replace
compat::u2f
with serde helpers (breaking) - RUST-739 Don't re-export types from unstable dependencies (breaking)
- RUST-789 Standardize on
ObjectId
conversion constructors (breaking) - RUST-788 Accept
impl AsRef<str>
instead of&str
inDocument
methods (breaking) - RUST-765 Ensure API follows Rust API Guidelines (breaking)
- RUST-889 Avoid going through hex string when deserializing
ObjectId
from raw bytes (#287)- Thanks @univerz for the POC for this!
- RUST-960 Remove
decimal128
feature flag and functionality (breaking) - RUST-882 Remove lossy
From<u64>
impl forBson
(#280) (breaking) - RUST-811
bson::DateTime
ergonomic improvements (breaking) - RUST-815 Truncate
chrono::DateTime
to millisecond precision when converting tobson::DateTime
(breaking) (thanks @vkill!) - RUST-826 Take ownership of
self
inObjectId::to_hex
(breaking) - RUST-672 Introduce new
BinarySubtype
case for user-defined values - RUST-838 Improve
bson::DateTime::now()
performance (thanks @pymongo!) - RUST-846 Unify
Display
andDebug
implementations forBson
- RUST-861 Support deserializing
ObjectId
from non self-describing formats (thanks for reporting @univerz!) - RUST-876 Quote keys in
Document
'sDisplay
implementation - RUST-996 Bump
rand
dependency to 0.8 (thanks @seanpianka!)
Bugfixes
- RUST-884 Support deserializing
DateTime
s between the year 10,000 and 99,999 - RUST-942 Generate 5 random bytes instead of 3 for ObjectIds (#284)
- RUST-713 Fix underflow on BSON array and binary deserialization (thanks @gperinazzo and @5225225!)
- RUST-799 Fix errors and panics caused by datetimes with large distance to epoch
- RUST-825 Update serde helpers to properly conform with RFC 3339 (ISO 8601) (breaking)