From 2eda0f1a616e0e1d2413012fc0d48aef31f90347 Mon Sep 17 00:00:00 2001 From: Alex Sayers Date: Tue, 4 May 2021 20:31:54 +0900 Subject: [PATCH] Optionally implement Arbitrary for Naive{Date,Time,DateTime} --- Cargo.toml | 1 + src/naive/date.rs | 9 +++++++++ src/naive/datetime/mod.rs | 1 + src/naive/time/mod.rs | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c823e23e..850bc2dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ pure-rust-locales = { version = "0.5.2", optional = true } criterion = { version = "0.4.0", optional = true } rkyv = {version = "0.7", optional = true} iana-time-zone = { version = "0.1.44", optional = true, features = ["fallback"] } +arbitrary = { version = "1.0.0", features = ["derive"], optional = true } [target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies] wasm-bindgen = { version = "0.2", optional = true } diff --git a/src/naive/date.rs b/src/naive/date.rs index ba89d608..603d9e5d 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -193,6 +193,15 @@ pub const MIN_DATE: NaiveDate = NaiveDate::MIN; #[deprecated(since = "0.4.20", note = "Use NaiveDate::MAX instead")] pub const MAX_DATE: NaiveDate = NaiveDate::MAX; +#[cfg(feature = "arbitrary")] +impl arbitrary::Arbitrary<'_> for NaiveDate { + fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result { + let year = u.int_in_range(MIN_YEAR..=MAX_YEAR)?; + let ord = u.int_in_range(1..=366)?; + NaiveDate::from_yo_opt(year, ord).ok_or(arbitrary::Error::IncorrectFormat) + } +} + // as it is hard to verify year flags in `NaiveDate::MIN` and `NaiveDate::MAX`, // we use a separate run-time test. #[test] diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs index b67c8733..f2cee59f 100644 --- a/src/naive/datetime/mod.rs +++ b/src/naive/datetime/mod.rs @@ -79,6 +79,7 @@ pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime::MAX; /// ``` #[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)] #[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct NaiveDateTime { date: NaiveDate, time: NaiveTime, diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index 44184f86..8fa1698e 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -194,6 +194,15 @@ pub struct NaiveTime { frac: u32, } +#[cfg(feature = "arbitrary")] +impl arbitrary::Arbitrary<'_> for NaiveTime { + fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result { + let secs = u.int_in_range(0..=86_400)?; + let frac = u.int_in_range(0..=2_000_000_000)?; + Ok(NaiveTime { secs, frac }) + } +} + impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute and second. ///