Skip to content

v2.0.0

Compare
Choose a tag to compare
@patrickfreed patrickfreed released this 07 Sep 18:30

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 from chrono (which is currently 0.4) in the Bson enum, the variant now wraps the bson::DateTime newtype defined within bson, and that newtype also no longer wraps a chrono::DateTime. This way the dependency on chrono can be updated to new semver breaking versions without having to update bson's major version.
    • To ease in the construction and usage of the newtype from chrono::DateTime, the chrono-0_4 feature flag can be enabled, which includes a From<chrono::DateTime> implementation for bson::DateTime and a From<bson::DateTime> implementation for chrono::DateTime, as well as some serde helpers.
  • Document::get_datetime returns a ValueAccessResult of &bson::DateTime instead of &chrono::DateTime
  • Bson::as_datetime returns an Option of &bson::DateTime instead of &chrono::DateTime
  • ObjectId::timestamp returns a crate::DateTime instead of chrono::DateTime
  • oid::Error no longer wraps hex::FromHexError (the hex crate is 0.4), see below for details.
  • The Uuid serde helpers, as well as From<Uuid> implementations for Bson and Binary, are now gated behind the uuid-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 into DeserializationError.
    • InvalidTimestamp(i64) => InvalidDateTime { key: String, datetime: i64 }
  • bson::ser::Error:
    • IoError => Io
    • InvalidMapKeyType { key: Bson } => InvalidDocumentKey(Bson)
    • UnsupportedUnsignedType => removed
    • UnsignedTypesValueExceededRange => UnsignedIntegerExceededRange(u64)
  • oid::Error:
    • ArgumentError => removed
    • FromHexError => removed, replaced by the new InvalidHexStringCharacter and InvalidHexStringLength 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 and document::DocumentIntoIterator renamed to document::Iter and document::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::Errors in Arcs.

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 ObjectIds 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 for ObjectId (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>> for Bson where T: Into<Bson>
  • RUST-841 Mark ObjectId::bytes as const
  • 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 with indexmap (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 in Document 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)
  • RUST-960 Remove decimal128 feature flag and functionality (breaking)
  • RUST-882 Remove lossy From<u64> impl for Bson (#280) (breaking)
  • RUST-811 bson::DateTime ergonomic improvements (breaking)
  • RUST-815 Truncate chrono::DateTime to millisecond precision when converting to bson::DateTime (breaking) (thanks @vkill!)
  • RUST-826 Take ownership of self in ObjectId::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 and Debug implementations for Bson
  • RUST-861 Support deserializing ObjectId from non self-describing formats (thanks for reporting @univerz!)
  • RUST-876 Quote keys in Document's Display implementation
  • RUST-996 Bump rand dependency to 0.8 (thanks @seanpianka!)

Bugfixes

  • RUST-884 Support deserializing DateTimes 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)