@@ -53,6 +53,7 @@ use std::path::PathBuf;
5353use std:: rc:: Rc ;
5454use std:: sync:: atomic:: { AtomicBool , AtomicIsize , AtomicUsize } ;
5555use 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) ]
12761305mod test {
12771306 use super :: * ;
@@ -1587,6 +1616,16 @@ 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 ! ( system_time. 0 , size_hint:: and( bool :: size_hint( 0 ) , Duration :: size_hint( 0 ) ) . 0 ) ;
1626+ // SystemTime::size_hint has no maximum
1627+ assert_eq ! ( system_time. 1 , None ) ;
1628+ }
15901629}
15911630
15921631/// Multiple conflicting arbitrary attributes are used on the same field:
0 commit comments