1- use crate :: fmt;
21use crate :: time:: Duration ;
2+ use crate :: { fmt, io} ;
33
44const NSEC_PER_SEC : u64 = 1_000_000_000 ;
55pub const UNIX_EPOCH : SystemTime = SystemTime { t : Timespec :: zero ( ) } ;
@@ -34,8 +34,8 @@ pub(crate) struct Timespec {
3434
3535impl SystemTime {
3636 #[ cfg_attr( any( target_os = "horizon" , target_os = "hurd" ) , allow( unused) ) ]
37- pub fn new ( tv_sec : i64 , tv_nsec : i64 ) -> SystemTime {
38- SystemTime { t : Timespec :: new ( tv_sec, tv_nsec) }
37+ pub fn new ( tv_sec : i64 , tv_nsec : i64 ) -> Result < SystemTime , io :: Error > {
38+ Ok ( SystemTime { t : Timespec :: new ( tv_sec, tv_nsec) ? } )
3939 }
4040
4141 pub fn now ( ) -> SystemTime {
@@ -55,12 +55,6 @@ impl SystemTime {
5555 }
5656}
5757
58- impl From < libc:: timespec > for SystemTime {
59- fn from ( t : libc:: timespec ) -> SystemTime {
60- SystemTime { t : Timespec :: from ( t) }
61- }
62- }
63-
6458impl fmt:: Debug for SystemTime {
6559 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
6660 f. debug_struct ( "SystemTime" )
@@ -71,11 +65,15 @@ impl fmt::Debug for SystemTime {
7165}
7266
7367impl Timespec {
68+ const unsafe fn new_unchecked ( tv_sec : i64 , tv_nsec : i64 ) -> Timespec {
69+ Timespec { tv_sec, tv_nsec : unsafe { Nanoseconds ( tv_nsec as u32 ) } }
70+ }
71+
7472 pub const fn zero ( ) -> Timespec {
75- Timespec :: new ( 0 , 0 )
73+ unsafe { Self :: new_unchecked ( 0 , 0 ) }
7674 }
7775
78- const fn new ( tv_sec : i64 , tv_nsec : i64 ) -> Timespec {
76+ const fn new ( tv_sec : i64 , tv_nsec : i64 ) -> Result < Timespec , io :: Error > {
7977 // On Apple OS, dates before epoch are represented differently than on other
8078 // Unix platforms: e.g. 1/10th of a second before epoch is represented as `seconds=-1`
8179 // and `nanoseconds=100_000_000` on other platforms, but is `seconds=0` and
@@ -100,9 +98,11 @@ impl Timespec {
10098 } else {
10199 ( tv_sec, tv_nsec)
102100 } ;
103- assert ! ( tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 ) ;
104- // SAFETY: The assert above checks tv_nsec is within the valid range
105- Timespec { tv_sec, tv_nsec : unsafe { Nanoseconds ( tv_nsec as u32 ) } }
101+ if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 {
102+ Ok ( unsafe { Self :: new_unchecked ( tv_sec, tv_nsec) } )
103+ } else {
104+ Err ( io:: const_io_error!( io:: ErrorKind :: InvalidData , "Invalid timestamp" ) )
105+ }
106106 }
107107
108108 pub fn now ( clock : libc:: clockid_t ) -> Timespec {
@@ -126,13 +126,15 @@ impl Timespec {
126126 if let Some ( clock_gettime64) = __clock_gettime64. get ( ) {
127127 let mut t = MaybeUninit :: uninit ( ) ;
128128 cvt ( unsafe { clock_gettime64 ( clock, t. as_mut_ptr ( ) ) } ) . unwrap ( ) ;
129- return Timespec :: from ( unsafe { t. assume_init ( ) } ) ;
129+ let t = unsafe { t. assume_init ( ) } ;
130+ return Timespec :: new ( t. tv_sec as i64 , t. tv_nsec as i64 ) . unwrap ( ) ;
130131 }
131132 }
132133
133134 let mut t = MaybeUninit :: uninit ( ) ;
134135 cvt ( unsafe { libc:: clock_gettime ( clock, t. as_mut_ptr ( ) ) } ) . unwrap ( ) ;
135- Timespec :: from ( unsafe { t. assume_init ( ) } )
136+ let t = unsafe { t. assume_init ( ) } ;
137+ Timespec :: new ( t. tv_sec as i64 , t. tv_nsec as i64 ) . unwrap ( )
136138 }
137139
138140 pub fn sub_timespec ( & self , other : & Timespec ) -> Result < Duration , Duration > {
@@ -178,7 +180,7 @@ impl Timespec {
178180 nsec -= NSEC_PER_SEC as u32 ;
179181 secs = secs. checked_add ( 1 ) ?;
180182 }
181- Some ( Timespec :: new ( secs, nsec. into ( ) ) )
183+ Some ( unsafe { Timespec :: new_unchecked ( secs, nsec. into ( ) ) } )
182184 }
183185
184186 pub fn checked_sub_duration ( & self , other : & Duration ) -> Option < Timespec > {
@@ -190,7 +192,7 @@ impl Timespec {
190192 nsec += NSEC_PER_SEC as i32 ;
191193 secs = secs. checked_sub ( 1 ) ?;
192194 }
193- Some ( Timespec :: new ( secs, nsec. into ( ) ) )
195+ Some ( unsafe { Timespec :: new_unchecked ( secs, nsec. into ( ) ) } )
194196 }
195197
196198 #[ allow( dead_code) ]
@@ -226,12 +228,6 @@ impl Timespec {
226228 }
227229}
228230
229- impl From < libc:: timespec > for Timespec {
230- fn from ( t : libc:: timespec ) -> Timespec {
231- Timespec :: new ( t. tv_sec as i64 , t. tv_nsec as i64 )
232- }
233- }
234-
235231#[ cfg( all(
236232 target_os = "linux" ,
237233 target_env = "gnu" ,
@@ -260,18 +256,6 @@ impl __timespec64 {
260256 }
261257}
262258
263- #[ cfg( all(
264- target_os = "linux" ,
265- target_env = "gnu" ,
266- target_pointer_width = "32" ,
267- not( target_arch = "riscv32" )
268- ) ) ]
269- impl From < __timespec64 > for Timespec {
270- fn from ( t : __timespec64 ) -> Timespec {
271- Timespec :: new ( t. tv_sec , t. tv_nsec . into ( ) )
272- }
273- }
274-
275259#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
276260pub struct Instant {
277261 t : Timespec ,
0 commit comments