Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for time v0.3 types #450

Merged
merged 5 commits into from May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Expand Up @@ -71,7 +71,7 @@ jobs:
# It is good to test more than the MSRV and stable since sometimes
# breakage occurs in intermediate versions.
# IMPORTANT: Synchronize the MSRV with the Cargo.toml values.
rust: ["1.46", "1.50", "1.55", "stable", "beta", "nightly"]
rust: ["1.53", "1.55", "1.60", "stable", "beta", "nightly"]
crate: ["serde_with", "serde_with_macros", "serde_with_test"]
runs-on: ${{ matrix.os }}
steps:
Expand Down
50 changes: 48 additions & 2 deletions serde_with/CHANGELOG.md
Expand Up @@ -7,6 +7,52 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

* Add support for `time` crate v0.3 #450

`time::Duration` can now be serialized with the `DurationSeconds` and related converters.

```rust
// Rust
#[serde_as(as = "serde_with::DurationSeconds<u64>")]
value: Duration,

// JSON
"value": 86400,
```

`time::OffsetDateTime` and `time::PrimitiveDateTime` can now be serialized with the `TimestampSeconds` and related converters.


```rust
// Rust
#[serde_as(as = "serde_with::TimestampMicroSecondsWithFrac<String>")]
value: time::PrimitiveDateTime,

// JSON
"value": "1000000",
```

`time::OffsetDateTime` can be serialized in string format in different well-known formats.
Two formats are supported, `time::format_description::well_known::Rfc2822` and `time::format_description::well_known::Rfc3339`.

```rust
// Rust
#[serde_as(as = "time::format_description::well_known::Rfc2822")]
rfc_2822: OffsetDateTime,
#[serde_as(as = "Vec<time::format_description::well_known::Rfc3339>")]
rfc_3339: Vec<OffsetDateTime>,

// JSON
"rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
"rfc_3339": ["1997-11-21T09:55:06-06:00"],
```

### Changed

* Bump MSRV to 1.53, since the new dependency `time` requires that version.

### Fixed

* Make the documentation clearer by stating that the `#[serde_as]` and `#[skip_serializing_none]` attributes must always be places before `#[derive]`.
Expand Down Expand Up @@ -143,9 +189,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

The `#[serde(borrow)]` annotation is automatically added by the `#[serde_as]` attribute.

## Changed
### Changed

* Bump MSRV to 1.46, since the dev-dependency bitflags requires that version now.
* Bump MSRV to 1.46, since the dev-dependency `bitflags` requires that version now.
* `flattened_maybe!` no longer requires the `serde_with` crate to be available with a specific name.
This allows renaming the crate or using `flattened_maybe!` through a re-export without any complications.

Expand Down
8 changes: 7 additions & 1 deletion serde_with/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ authors = [
"Marcin Kaźmierczak",
]
name = "serde_with"
rust-version = "1.46"
rust-version = "1.53"
version = "1.13.0"

categories = ["encoding"]
Expand Down Expand Up @@ -43,6 +43,7 @@ rustversion = "1.0.0"
serde = {version = "1.0.122", features = ["derive"]}
serde_json = {version = "1.0.1", optional = true}
serde_with_macros = {path = "../serde_with_macros", version = "1.5.2", optional = true}
time_0_3 = {package = "time", version = "~0.3", optional = true, features = ["serde-well-known"]}

[dev-dependencies]
expect-test = "1.0.0"
Expand Down Expand Up @@ -89,6 +90,11 @@ name = "serde_as"
path = "tests/serde_as/lib.rs"
required-features = ["macros"]

[[test]]
name = "time_0_3"
path = "tests/time_0_3.rs"
required-features = ["macros", "time_0_3"]

[[test]]
name = "derives"
path = "tests/derives/lib.rs"
Expand Down
8 changes: 8 additions & 0 deletions serde_with/src/guide/feature_flags.md
Expand Up @@ -10,6 +10,7 @@ Each entry will explain the feature in more detail.
5. [`indexmap`](#indexmap)
6. [`json`](#json)
7. [`macros`](#macros)
8. [`time_0_3`](#time_0_3)

## `base64`

Expand Down Expand Up @@ -52,3 +53,10 @@ The `macros` features enables all helper macros and derives.
It is enabled by default, since the macros provide a usability benefit, especially for `serde_as`.

This pulls in `serde_with_macros` as a dependency.

## `time_0_3`

The `time_0_3` enables integration of `time` v0.3 specific conversions.
This includes support for the timestamp and duration types.

This pulls in `time` v0.3 as a dependency.
29 changes: 29 additions & 0 deletions serde_with/src/guide/serde_as_transformations.md
Expand Up @@ -23,6 +23,7 @@ This page lists the transformations implemented in this crate and supported by `
19. [Timestamps as seconds since UNIX epoch](#timestamps-as-seconds-since-unix-epoch)
20. [Value into JSON String](#value-into-json-string)
21. [`Vec` of tuples to `Maps`](#vec-of-tuples-to-maps)
22. [Well-known time formats for `OffsetDateTime`](#well-known-time-formats-for-offsetdatetime)

## Base64 encode bytes

Expand Down Expand Up @@ -212,6 +213,8 @@ value: Duration,

The same conversions are also implemented for [`chrono::Duration`] with the `chrono` feature.

The same conversions are also implemented for [`time::Duration`] with the `time_0_3` feature.

## Hex encode bytes

[`Hex`]
Expand Down Expand Up @@ -405,6 +408,8 @@ value: SystemTime,

The same conversions are also implemented for [`chrono::DateTime<Utc>`], [`chrono::DateTime<Local>`], and [`chrono::NaiveDateTime`] with the `chrono` feature.

The conversions are availble for [`time::OffsetDateTime`] and [`time::PrimitiveDateTime`] with the `time_0_3` feature enabled.

## Value into JSON String

Some JSON APIs are weird and return a JSON encoded string in a JSON response
Expand Down Expand Up @@ -446,6 +451,25 @@ This includes `BinaryHeap<(K, V)>`, `BTreeSet<(K, V)>`, `HashSet<(K, V)>`, `Link

The [inverse operation](#maps-to-vec-of-tuples) is also available.

## Well-known time formats for `OffsetDateTime`

[`time::OffsetDateTime`] can be serialized in string format in different well-known formats.
Two formats are supported, [`time::format_description::well_known::Rfc2822`] and [`time::format_description::well_known::Rfc3339`].

```ignore
// Rust
#[serde_as(as = "time::format_description::well_known::Rfc2822")]
rfc_2822: OffsetDateTime,
#[serde_as(as = "time::format_description::well_known::Rfc3339")]
rfc_3339: OffsetDateTime,

// JSON
"rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
"rfc_3339": "1997-11-21T09:55:06-06:00",
```

These conversions are availble with the `time_0_3` feature flag.

[`Base64`]: crate::base64::Base64
[`Bytes`]: crate::Bytes
[`chrono::DateTime<Local>`]: chrono_crate::DateTime
Expand All @@ -464,6 +488,11 @@ The [inverse operation](#maps-to-vec-of-tuples) is also available.
[`NoneAsEmptyString`]: crate::NoneAsEmptyString
[`OneOrMany`]: crate::OneOrMany
[`PickFirst`]: crate::PickFirst
[`time::Duration`]: time_0_3::Duration
[`time::format_description::well_known::Rfc2822`]: time_0_3::format_description::well_known::Rfc2822
[`time::format_description::well_known::Rfc3339`]: time_0_3::format_description::well_known::Rfc3339
[`time::OffsetDateTime`]: time_0_3::OffsetDateTime
[`time::PrimitiveDateTime`]: time_0_3::PrimitiveDateTime
[`TimestampSeconds`]: crate::TimestampSeconds
[`TimestampSecondsWithFrac`]: crate::TimestampSecondsWithFrac
[`TryFromInto`]: crate::TryFromInto
Expand Down
19 changes: 19 additions & 0 deletions serde_with/src/lib.rs
Expand Up @@ -279,6 +279,9 @@ pub mod json;
pub mod rust;
pub mod ser;
mod serde_conv;
#[cfg(feature = "time_0_3")]
#[cfg_attr(docsrs, doc(cfg(feature = "time_0_3")))]
pub mod time_0_3;
mod utils;
#[doc(hidden)]
pub mod with_prefix;
Expand Down Expand Up @@ -746,13 +749,16 @@ pub struct BytesOrString;
/// For example, deserializing `DurationSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
///
/// This type also supports [`chrono::Duration`] with the `chrono`-[feature flag].
/// This type also supports [`time::Duration`][::time_0_3::Duration] with the `time_0_3`-[feature flag].
///
/// | Duration Type | Converter | Available `FORMAT`s |
/// | --------------------- | ------------------------- | ---------------------- |
/// | `std::time::Duration` | `DurationSeconds` | `u64`, `f64`, `String` |
/// | `std::time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
/// | `chrono::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
/// | `chrono::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
/// | `time::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
/// | `time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
///
/// # Examples
///
Expand Down Expand Up @@ -886,13 +892,16 @@ pub struct DurationSeconds<
/// For example, deserializing `DurationSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
///
/// This type also supports [`chrono::Duration`] with the `chrono`-[feature flag].
/// This type also supports [`time::Duration`][::time_0_3::Duration] with the `time_0_3`-[feature flag].
///
/// | Duration Type | Converter | Available `FORMAT`s |
/// | --------------------- | ------------------------- | ---------------------- |
/// | `std::time::Duration` | `DurationSeconds` | `u64`, `f64`, `String` |
/// | `std::time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
/// | `chrono::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
/// | `chrono::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
/// | `time::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
/// | `time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
///
/// # Examples
///
Expand Down Expand Up @@ -1066,6 +1075,7 @@ pub struct DurationNanoSecondsWithFrac<
/// For example, deserializing `TimestampSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
///
/// This type also supports [`chrono::DateTime`][DateTime] with the `chrono`-[feature flag].
/// This type also supports [`time::OffsetDateTime`][::time_0_3::OffsetDateTime] and [`time::PrimitiveDateTime`][::time_0_3::PrimitiveDateTime] with the `time_0_3`-[feature flag].
///
/// | Timestamp Type | Converter | Available `FORMAT`s |
/// | ------------------------- | -------------------------- | ---------------------- |
Expand All @@ -1075,6 +1085,10 @@ pub struct DurationNanoSecondsWithFrac<
/// | `chrono::DateTime<Utc>` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `chrono::DateTime<Local>` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `chrono::DateTime<Local>` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `time::OffsetDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `time::OffsetDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `time::PrimitiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `time::PrimitiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
///
/// # Examples
///
Expand Down Expand Up @@ -1209,6 +1223,7 @@ pub struct TimestampSeconds<
/// For example, deserializing `TimestampSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
///
/// This type also supports [`chrono::DateTime`][DateTime] and [`chrono::NaiveDateTime`][NaiveDateTime] with the `chrono`-[feature flag].
/// This type also supports [`time::OffsetDateTime`][::time_0_3::OffsetDateTime] and [`time::PrimitiveDateTime`][::time_0_3::PrimitiveDateTime] with the `time_0_3`-[feature flag].
///
/// | Timestamp Type | Converter | Available `FORMAT`s |
/// | ------------------------- | -------------------------- | ---------------------- |
Expand All @@ -1220,6 +1235,10 @@ pub struct TimestampSeconds<
/// | `chrono::DateTime<Local>` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `chrono::NaiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `chrono::NaiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `time::OffsetDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `time::OffsetDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
/// | `time::PrimitiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
/// | `time::PrimitiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
///
/// # Examples
///
Expand Down