Skip to content

Commit 09a8cbb

Browse files
drshikaabr-egnisabelatkinson
authored
RUST-1699: Add serde_with 3.x integration (#422)
* RUST-1699: Add serde_with 3.x integration Co-authored-by: Abraham Egnor <[email protected]> Co-authored-by: Isabel Atkinson <[email protected]>
1 parent b243db1 commit 09a8cbb

File tree

7 files changed

+184
-31
lines changed

7 files changed

+184
-31
lines changed

.evergreen/Cargo.lock.msrv

Lines changed: 82 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.evergreen/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ axes:
195195
- id: "extra-rust-versions"
196196
values:
197197
- id: "min"
198-
display_name: "1.56 (minimum supported version)"
198+
display_name: "1.60 (minimum supported version)"
199199
variables:
200-
RUST_VERSION: "1.56.0"
200+
RUST_VERSION: "1.60.0"
201201
MSRV: "true"
202202
- id: "nightly"
203203
display_name: "nightly"

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ once_cell = "1.5.1"
6565
uuid-0_8 = { package = "uuid", version = "0.8.1", features = ["serde", "v4"], optional = true }
6666
uuid = { version = "1.1.2", features = ["serde", "v4"] }
6767
serde_bytes = "0.11.5"
68-
serde_with = { version = "1", optional = true }
68+
serde_with = { version = "1.3.1", optional = true }
69+
serde_with-3 = { package = "serde_with", version = "3.1.0", optional = true }
6970
time = { version = "0.3.9", features = ["formatting", "parsing", "macros", "large-dates"] }
7071
bitvec = "1.0.1"
7172

7273
[target.'cfg(target_arch = "wasm32")'.dependencies]
7374
js-sys = "0.3"
74-
7575
[dev-dependencies]
7676
assert_matches = "1.2"
7777
criterion = "0.3.0"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ Note that if you are using `bson` through the `mongodb` crate, you do not need t
5050
| `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 |
5151
| `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 |
5252
| `uuid-1` | Enable support for v1.x of the [`uuid`](https://docs.rs/uuid/1.0) crate in the public API. | n/a | no |
53-
| `serde_with` | Enable [`serde_with`](https://docs.rs/serde_with/latest) integrations for `bson::DateTime` and `bson::Uuid` | serde_with | no |
54-
53+
| `serde_with` | Enable [`serde_with`](https://docs.rs/serde_with/1.x) 1.x integrations for `bson::DateTime` and `bson::Uuid`.| serde_with | no |
54+
| `serde_with-3` | Enable [`serde_with`](https://docs.rs/serde_with/3.x) 3.x integrations for `bson::DateTime` and `bson::Uuid`. Requires Rust 1.61. | serde_with | no |
5555
## Overview of the BSON Format
5656

5757
BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents.

src/datetime.rs

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,20 @@ use serde_with::{DeserializeAs, SerializeAs};
145145
/// }
146146
/// # }
147147
/// ```
148-
/// ### The `serde_with` feature flag
148+
/// ### The `serde_with-3` feature flag
149149
///
150-
/// The `serde_with` feature can be enabled to support more ergonomic serde attributes for
150+
/// The `serde_with-3` feature can be enabled to support more ergonomic serde attributes for
151151
/// (de)serializing [`chrono::DateTime`] from/to BSON via the [`serde_with`](https://docs.rs/serde_with/1.11.0/serde_with/)
152-
/// crate. The main benefit of this compared to the regular `serde_helpers` is that `serde_with` can
153-
/// handle nested [`chrono::DateTime`] values (e.g. in [`Option`]), whereas the former only works on
154-
/// fields that are exactly [`chrono::DateTime`].
152+
/// crate. The main benefit of this compared to the regular `serde_helpers` is that `serde_with-3`
153+
/// can handle nested [`chrono::DateTime`] values (e.g. in [`Option`]), whereas the former only
154+
/// works on fields that are exactly [`chrono::DateTime`].
155155
/// ```
156-
/// # #[cfg(all(feature = "chrono-0_4", feature = "serde_with"))]
156+
/// # #[cfg(all(feature = "chrono-0_4", feature = "serde_with-3"))]
157157
/// # {
158158
/// use serde::{Deserialize, Serialize};
159159
/// use bson::doc;
160160
///
161-
/// #[serde_with::serde_as]
161+
/// #[serde_with_3::serde_as]
162162
/// #[derive(Deserialize, Serialize, PartialEq, Debug)]
163163
/// struct Foo {
164164
/// /// Serializes as a BSON datetime rather than using [`chrono::DateTime`]'s serialization
@@ -482,6 +482,36 @@ impl SerializeAs<chrono::DateTime<Utc>> for crate::DateTime {
482482
}
483483
}
484484

485+
#[cfg(all(feature = "chrono-0_4", feature = "serde_with-3"))]
486+
#[cfg_attr(
487+
docsrs,
488+
doc(cfg(all(feature = "chrono-0_4", feature = "serde_with-3")))
489+
)]
490+
impl<'de> serde_with_3::DeserializeAs<'de, chrono::DateTime<Utc>> for crate::DateTime {
491+
fn deserialize_as<D>(deserializer: D) -> std::result::Result<chrono::DateTime<Utc>, D::Error>
492+
where
493+
D: Deserializer<'de>,
494+
{
495+
let dt = DateTime::deserialize(deserializer)?;
496+
Ok(dt.to_chrono())
497+
}
498+
}
499+
500+
#[cfg(all(feature = "chrono-0_4", feature = "serde_with-3"))]
501+
#[cfg_attr(docsrs, doc(cfg(all(feature = "chrono-0_4", feature = "chrono-0_4"))))]
502+
impl serde_with_3::SerializeAs<chrono::DateTime<Utc>> for crate::DateTime {
503+
fn serialize_as<S>(
504+
source: &chrono::DateTime<Utc>,
505+
serializer: S,
506+
) -> std::result::Result<S::Ok, S::Error>
507+
where
508+
S: serde::Serializer,
509+
{
510+
let dt = DateTime::from_chrono(*source);
511+
dt.serialize(serializer)
512+
}
513+
}
514+
485515
#[cfg(feature = "time-0_3")]
486516
#[cfg_attr(docsrs, doc(cfg(feature = "time-0_3")))]
487517
impl From<crate::DateTime> for time::OffsetDateTime {
@@ -525,6 +555,33 @@ impl SerializeAs<time::OffsetDateTime> for crate::DateTime {
525555
}
526556
}
527557

558+
#[cfg(all(feature = "time-0_3", feature = "serde_with-3"))]
559+
#[cfg_attr(docsrs, doc(cfg(all(feature = "time-0_3", feature = "serde_with-3"))))]
560+
impl<'de> serde_with_3::DeserializeAs<'de, time::OffsetDateTime> for crate::DateTime {
561+
fn deserialize_as<D>(deserializer: D) -> std::result::Result<time::OffsetDateTime, D::Error>
562+
where
563+
D: Deserializer<'de>,
564+
{
565+
let dt = DateTime::deserialize(deserializer)?;
566+
Ok(dt.to_time_0_3())
567+
}
568+
}
569+
570+
#[cfg(all(feature = "time-0_3", feature = "serde_with-3"))]
571+
#[cfg_attr(docsrs, doc(cfg(all(feature = "time-0_3", feature = "chrono-0_4"))))]
572+
impl serde_with_3::SerializeAs<time::OffsetDateTime> for crate::DateTime {
573+
fn serialize_as<S>(
574+
source: &time::OffsetDateTime,
575+
serializer: S,
576+
) -> std::result::Result<S::Ok, S::Error>
577+
where
578+
S: serde::Serializer,
579+
{
580+
let dt = DateTime::from_time_0_3(*source);
581+
dt.serialize(serializer)
582+
}
583+
}
584+
528585
/// Errors that can occur during [`DateTime`] construction and generation.
529586
#[derive(Clone, Debug)]
530587
#[non_exhaustive]

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
//!
4444
//! ## Installation
4545
//! ### Requirements
46-
//! - Rust 1.56+
46+
//! - Rust 1.60+
4747
//!
4848
//! ### Importing
4949
//! This crate is available on [crates.io](https://crates.io/crates/bson). To use it in your application,
@@ -267,7 +267,7 @@
267267
//!
268268
//! ## Minimum supported Rust version (MSRV)
269269
//!
270-
//! The MSRV for this crate is currently 1.56.0. This will be rarely be increased, and if it ever is,
270+
//! The MSRV for this crate is currently 1.60.0. This will be rarely be increased, and if it ever is,
271271
//! it will only happen in a minor or major version release.
272272
273273
#![allow(clippy::cognitive_complexity, clippy::derive_partial_eq_without_eq)]

src/uuid/mod.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,21 @@
7474
//! For backwards compatibility, a `uuid-0_8` feature flag can be enabled, which provides the same
7575
//! API for interoperation with version 0.8 of the `uuid` crate.
7676
//!
77-
//! ## The `serde_with` feature flag
77+
//! ## The `serde_with-3` feature flag
7878
//!
79-
//! The `serde_with` feature can be enabled to support more ergonomic serde attributes for
79+
//! The `serde_with-3` feature can be enabled to support more ergonomic serde attributes for
8080
//! (de)serializing [`uuid::Uuid`] from/to BSON via the [`serde_with`](https://docs.rs/serde_with/1.11.0/serde_with/)
81-
//! crate. The main benefit of this compared to the regular `serde_helpers` is that `serde_with` can
82-
//! handle nested [`uuid::Uuid`] values (e.g. in [`Option`]), whereas the former only works on
81+
//! crate. The main benefit of this compared to the regular `serde_helpers` is that `serde_with-3`
82+
//! can handle nested [`uuid::Uuid`] values (e.g. in [`Option`]), whereas the former only works on
8383
//! fields that are exactly [`uuid::Uuid`].
8484
//! ```
85-
//! # #[cfg(all(feature = "uuid-1", feature = "serde_with"))]
85+
//! # #[cfg(all(feature = "uuid-1", feature = "serde_with-3"))]
8686
//! # {
8787
//! # use uuid as uuid;
8888
//! use serde::{Deserialize, Serialize};
8989
//! use bson::doc;
9090
//!
91-
//! #[serde_with::serde_as]
91+
//! #[serde_with_3::serde_as]
9292
//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
9393
//! struct Foo {
9494
//! /// Serializes as a BSON binary rather than using [`uuid::Uuid`]'s serialization
@@ -509,6 +509,30 @@ macro_rules! trait_impls {
509509
uuid.serialize(serializer)
510510
}
511511
}
512+
513+
#[cfg(all($feat, feature = "serde_with-3"))]
514+
#[cfg_attr(docsrs, doc(cfg(all($feat, feature = "serde_with-3"))))]
515+
impl<'de> serde_with_3::DeserializeAs<'de, $u> for crate::Uuid {
516+
fn deserialize_as<D>(deserializer: D) -> std::result::Result<$u, D::Error>
517+
where
518+
D: serde::Deserializer<'de>,
519+
{
520+
let uuid = Uuid::deserialize(deserializer)?;
521+
Ok(uuid.into())
522+
}
523+
}
524+
525+
#[cfg(all($feat, feature = "serde_with_3"))]
526+
#[cfg_attr(docsrs, doc(cfg(all($feat, feature = "serde_with_3"))))]
527+
impl serde_with_3::SerializeAs<$u> for crate::Uuid {
528+
fn serialize_as<S>(source: &$u, serializer: S) -> std::result::Result<S::Ok, S::Error>
529+
where
530+
S: serde::Serializer,
531+
{
532+
let uuid = Uuid::from(*source);
533+
uuid.serialize(serializer)
534+
}
535+
}
512536
};
513537
}
514538
trait_impls!(feature = "uuid-0_8", uuid_0_8::Uuid);

0 commit comments

Comments
 (0)