@@ -43,7 +43,7 @@ use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZ
43
43
use core:: ops:: { Range , RangeBounds , RangeFrom , RangeInclusive , RangeTo , RangeToInclusive } ;
44
44
use core:: str;
45
45
use core:: time:: Duration ;
46
- use std:: borrow:: { Cow , ToOwned } ;
46
+ use std:: borrow:: Cow ;
47
47
use std:: collections:: { BTreeMap , BTreeSet , BinaryHeap , HashMap , HashSet , LinkedList , VecDeque } ;
48
48
use std:: ffi:: { CString , OsString } ;
49
49
use std:: hash:: BuildHasher ;
@@ -53,6 +53,7 @@ use std::path::PathBuf;
53
53
use std:: rc:: Rc ;
54
54
use std:: sync:: atomic:: { AtomicBool , AtomicIsize , AtomicUsize } ;
55
55
use std:: sync:: { Arc , Mutex } ;
56
+ use std:: time:: SystemTime ;
56
57
57
58
/// Generate arbitrary structured values from raw, unstructured data.
58
59
///
@@ -1272,6 +1273,32 @@ impl<'a> Arbitrary<'a> for SocketAddr {
1272
1273
}
1273
1274
}
1274
1275
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 if let Some ( system_time) = SystemTime :: UNIX_EPOCH . checked_sub ( duration) {
1288
+ return Ok ( system_time) ;
1289
+ }
1290
+ }
1291
+ }
1292
+
1293
+ fn size_hint ( depth : usize ) -> ( usize , Option < usize > ) {
1294
+ size_hint:: and_all ( & [
1295
+ bool:: size_hint ( depth) ,
1296
+ Duration :: size_hint ( depth) ,
1297
+ ( 0 , None ) ,
1298
+ ] )
1299
+ }
1300
+ }
1301
+
1275
1302
#[ cfg( test) ]
1276
1303
mod test {
1277
1304
use super :: * ;
@@ -1587,6 +1614,19 @@ mod test {
1587
1614
) ;
1588
1615
assert_eq ! ( ( 1 , None ) , <( u8 , Vec <u8 >) as Arbitrary >:: size_hint( 0 ) ) ;
1589
1616
}
1617
+
1618
+ #[ test]
1619
+ fn size_hint_for_system_time ( ) {
1620
+ let system_time = SystemTime :: size_hint ( 0 ) ;
1621
+
1622
+ // SystemTime::size_hint as minimum of bool + Duration
1623
+ assert_eq ! (
1624
+ system_time. 0 ,
1625
+ size_hint:: and( bool :: size_hint( 0 ) , Duration :: size_hint( 0 ) ) . 0
1626
+ ) ;
1627
+ // SystemTime::size_hint has no maximum
1628
+ assert_eq ! ( system_time. 1 , None ) ;
1629
+ }
1590
1630
}
1591
1631
1592
1632
/// Multiple conflicting arbitrary attributes are used on the same field:
0 commit comments