Skip to content

Commit 4e1033b

Browse files
committed
impl Arbitrary for SystemTime
1 parent 803f2df commit 4e1033b

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use std::path::PathBuf;
5353
use std::rc::Rc;
5454
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
5555
use std::sync::{Arc, Mutex};
56+
use std::time::SystemTime;
5657

5758
/// Generate arbitrary structured values from raw, unstructured data.
5859
///
@@ -1272,6 +1273,34 @@ impl<'a> Arbitrary<'a> for SocketAddr {
12721273
}
12731274
}
12741275

1276+
impl<'a> Arbitrary<'a> for SystemTime {
1277+
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1278+
// Create a SystemTime by adding or subtracting a duration from epoch.
1279+
// The result is not guaranteed to fit. Keep trying until a good SystemTime if found.
1280+
loop {
1281+
let add: bool = u.arbitrary()?;
1282+
let duration: Duration = u.arbitrary()?;
1283+
if add {
1284+
if let Some(system_time) = SystemTime::UNIX_EPOCH.checked_add(duration) {
1285+
return Ok(system_time);
1286+
}
1287+
} else {
1288+
if let Some(system_time) = SystemTime::UNIX_EPOCH.checked_sub(duration) {
1289+
return Ok(system_time);
1290+
}
1291+
}
1292+
}
1293+
}
1294+
1295+
fn size_hint(depth: usize) -> (usize, Option<usize>) {
1296+
size_hint::and_all(&[
1297+
bool::size_hint(depth),
1298+
Duration::size_hint(depth),
1299+
(0, None),
1300+
])
1301+
}
1302+
}
1303+
12751304
#[cfg(test)]
12761305
mod test {
12771306
use super::*;
@@ -1587,6 +1616,19 @@ mod test {
15871616
);
15881617
assert_eq!((1, None), <(u8, Vec<u8>) as Arbitrary>::size_hint(0));
15891618
}
1619+
1620+
#[test]
1621+
fn size_hint_for_system_time() {
1622+
let system_time = SystemTime::size_hint(0);
1623+
1624+
// SystemTime::size_hint as minimum of bool + Duration
1625+
assert_eq!(
1626+
system_time.0,
1627+
size_hint::and(bool::size_hint(0), Duration::size_hint(0)).0
1628+
);
1629+
// SystemTime::size_hint has no maximum
1630+
assert_eq!(system_time.1, None);
1631+
}
15901632
}
15911633

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

0 commit comments

Comments
 (0)