Skip to content

Commit

Permalink
impl Arbitrary for SystemTime
Browse files Browse the repository at this point in the history
  • Loading branch information
caspermeijn committed Mar 15, 2024
1 parent 803f2df commit 4e1033b
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
use std::sync::{Arc, Mutex};
use std::time::SystemTime;

/// Generate arbitrary structured values from raw, unstructured data.
///
Expand Down Expand Up @@ -1272,6 +1273,34 @@ impl<'a> Arbitrary<'a> for SocketAddr {
}
}

impl<'a> Arbitrary<'a> for SystemTime {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
// Create a SystemTime by adding or subtracting a duration from epoch.
// The result is not guaranteed to fit. Keep trying until a good SystemTime if found.
loop {
let add: bool = u.arbitrary()?;
let duration: Duration = u.arbitrary()?;
if add {
if let Some(system_time) = SystemTime::UNIX_EPOCH.checked_add(duration) {
return Ok(system_time);
}
} else {
if let Some(system_time) = SystemTime::UNIX_EPOCH.checked_sub(duration) {
return Ok(system_time);
}
}
}
}

fn size_hint(depth: usize) -> (usize, Option<usize>) {
size_hint::and_all(&[
bool::size_hint(depth),
Duration::size_hint(depth),
(0, None),
])
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -1587,6 +1616,19 @@ mod test {
);
assert_eq!((1, None), <(u8, Vec<u8>) as Arbitrary>::size_hint(0));
}

#[test]
fn size_hint_for_system_time() {
let system_time = SystemTime::size_hint(0);

// SystemTime::size_hint as minimum of bool + Duration
assert_eq!(
system_time.0,
size_hint::and(bool::size_hint(0), Duration::size_hint(0)).0
);
// SystemTime::size_hint has no maximum
assert_eq!(system_time.1, None);
}
}

/// Multiple conflicting arbitrary attributes are used on the same field:
Expand Down

0 comments on commit 4e1033b

Please sign in to comment.