Skip to content

Commit

Permalink
Expose rkyv features as features for chrono users.
Browse files Browse the repository at this point in the history
rkyv by default serializes usize as u32. This isn't ideal
on most modern platforms and unfortunately is configured through
a feature flag.

If we just set `default-features = false` in the rkyv Cargo
dependency, the crate fails to compile because all the size features
are mutually exclusive. On the other hand if we want to
e.g., change the serialization of usize to 64-bit and
we also want to use chrono this currently fails to compile
because chrono always enables rkyv/size_32.

This re-exports the relevant rkyv features so users can
choose which serialization to enable. The approach
is similar to what the ordered-float crate does:

https://github.com/reem/rust-ordered-float/blob/8111b345372632893af0b8aa12152f3dc7278aba/Cargo.toml#L37

Signed-off-by: Gerd Zellweger <mail@gerdzellweger.com>
  • Loading branch information
gz committed Dec 14, 2023
1 parent 5aaf742 commit 3728017
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 34 deletions.
11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rust-version = "1.57.0"
name = "chrono"

[features]
# Don't forget to adjust `ALL_NON_EXCLUSIVE_FEATURES` in CI scripts when adding a feature or an optional dependency.
default = ["clock", "std", "wasmbind"]
alloc = []
libc = []
Expand All @@ -25,12 +26,20 @@ std = ["alloc"]
clock = ["std", "winapi", "iana-time-zone", "android-tzdata"]
wasmbind = ["wasm-bindgen", "js-sys"]
unstable-locales = ["pure-rust-locales"]
rkyv = ["rkyv-32"]
# Note that rkyv-16, rkyv-32, and rkyv-64 are mutually exclusive.
rkyv-16 = ["dep:rkyv", "rkyv?/size_16"]
rkyv-32 = ["dep:rkyv", "rkyv?/size_32"]
rkyv-64 = ["dep:rkyv", "rkyv?/size_64"]
rkyv-validation = ["rkyv?/validation"]
# Features for internal use only:
__internal_bench = []
__internal-rkyv = ["dep:rkyv"]

[dependencies]
serde = { version = "1.0.99", default-features = false, optional = true }
pure-rust-locales = { version = "0.7", optional = true }
rkyv = { version = "0.7", optional = true }
rkyv = { version = "0.7", optional = true, default-features = false }
arbitrary = { version = "1.0.0", features = ["derive"], optional = true }

[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
Expand Down
7 changes: 5 additions & 2 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::offset::Local;
use crate::offset::{FixedOffset, Offset, TimeZone, Utc};
use crate::{Datelike, Months, TimeDelta, Timelike, Weekday};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

/// documented at re-export site
Expand Down Expand Up @@ -73,7 +73,10 @@ pub enum SecondsFormat {
/// the general-purpose constructors are all via the methods on the
/// [`TimeZone`](./offset/trait.TimeZone.html) implementations.
#[derive(Clone)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
pub struct DateTime<Tz: TimeZone> {
datetime: NaiveDateTime,
offset: Tz::Offset,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ pub mod serde {
/// Zero-copy serialization/deserialization with rkyv.
///
/// This module re-exports the `Archived*` versions of chrono's types.
#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
pub mod rkyv {
pub use crate::datetime::ArchivedDateTime;
pub use crate::month::ArchivedMonth;
Expand Down
9 changes: 6 additions & 3 deletions src/month.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt;

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use crate::OutOfRange;
Expand Down Expand Up @@ -29,9 +29,12 @@ use crate::OutOfRange;
/// Can be Serialized/Deserialized with serde
// Actual implementation is zero-indexed, API intended as 1-indexed for more intuitive behavior.
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down
9 changes: 6 additions & 3 deletions src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::iter::FusedIterator;
use core::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
use core::{fmt, str};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

/// L10n locales.
Expand Down Expand Up @@ -190,9 +190,12 @@ impl Days {
///
/// [proleptic Gregorian date]: crate::NaiveDate#calendar-date
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
pub struct NaiveDate {
Expand Down
9 changes: 6 additions & 3 deletions src/naive/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::time::Duration;
use core::{fmt, str};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -72,9 +72,12 @@ pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime::MAX;
/// assert_eq!(dt.num_seconds_from_midnight(), 33011);
/// ```
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down
9 changes: 6 additions & 3 deletions src/naive/isoweek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use core::fmt;

use super::internals::{DateImpl, Of, YearFlags};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

/// ISO 8601 week.
Expand All @@ -17,9 +17,12 @@ use rkyv::{Archive, Deserialize, Serialize};
/// One can retrieve this type from the existing [`Datelike`](../trait.Datelike.html) types
/// via the [`Datelike::iso_week`](../trait.Datelike.html#tymethod.iso_week) method.
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
pub struct IsoWeek {
Expand Down
9 changes: 6 additions & 3 deletions src/naive/time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::time::Duration;
use core::{fmt, str};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -199,9 +199,12 @@ mod tests;
/// Since Chrono alone cannot determine any existence of leap seconds,
/// **there is absolutely no guarantee that the leap second read has actually happened**.
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
pub struct NaiveTime {
Expand Down
12 changes: 9 additions & 3 deletions src/offset/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use core::fmt;
use core::str::FromStr;

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use super::{LocalResult, Offset, TimeZone};
Expand All @@ -20,8 +20,14 @@ use crate::{NaiveDateTime, ParseError};
/// `DateTime<FixedOffset>` instances. See the [`east_opt`](#method.east_opt) and
/// [`west_opt`](#method.west_opt) methods for examples.
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug)))]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug))
)]
pub struct FixedOffset {
local_minus_utc: i32,
}
Expand Down
12 changes: 9 additions & 3 deletions src/offset/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

//! The local (system) time zone.

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use super::fixed::FixedOffset;
Expand Down Expand Up @@ -101,8 +101,14 @@ mod tz_info;
/// assert!(dt1 >= dt2);
/// ```
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, Debug)))]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, Debug))
)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Local;

Expand Down
12 changes: 9 additions & 3 deletions src/offset/utc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use core::fmt;
))]
use std::time::{SystemTime, UNIX_EPOCH};

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use super::{FixedOffset, LocalResult, Offset, TimeZone};
Expand All @@ -40,8 +40,14 @@ use crate::DateTime;
/// assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), dt);
/// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash)))]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash))
)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Utc;

Expand Down
9 changes: 6 additions & 3 deletions src/time_delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use core::{fmt, i64};
#[cfg(feature = "std")]
use std::error::Error;

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

/// The number of nanoseconds in a microsecond.
Expand Down Expand Up @@ -51,9 +51,12 @@ macro_rules! try_opt {
///
/// This also allows for the negative duration; see individual methods for details.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
pub struct TimeDelta {
Expand Down
12 changes: 9 additions & 3 deletions src/weekday.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt;

#[cfg(feature = "rkyv")]
#[cfg(feature = "__internal-rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use crate::OutOfRange;
Expand Down Expand Up @@ -30,8 +30,14 @@ use crate::OutOfRange;
/// assert_eq!(sunday.pred(), Weekday::Sat);
/// ```
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash)))]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
derive(Archive, Deserialize, Serialize)
)]
#[cfg_attr(
any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"),
archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash))
)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Weekday {
/// Monday.
Expand Down

0 comments on commit 3728017

Please sign in to comment.