@@ -31,6 +31,7 @@ extern crate libc;
3131use std:: io:: BufReader ;
3232use std:: num;
3333use std:: string:: String ;
34+ use std:: time:: Duration ;
3435
3536static NSEC_PER_SEC : i32 = 1_000_000_000_i32 ;
3637
@@ -90,10 +91,15 @@ impl Timespec {
9091 }
9192}
9293
93- impl Add < Timespec , Timespec > for Timespec {
94- fn add ( & self , other : & Timespec ) -> Timespec {
95- let mut sec = self . sec + other. sec ;
96- let mut nsec = self . nsec + other. nsec ;
94+ impl Add < Duration , Timespec > for Timespec {
95+ fn add ( & self , other : & Duration ) -> Timespec {
96+ let d_sec = other. num_seconds ( ) ;
97+ // It is safe to unwrap the nanoseconds, because there cannot be
98+ // more than one second left, which fits in i64 and in i32.
99+ let d_nsec = ( other - Duration :: seconds ( d_sec) )
100+ . num_nanoseconds ( ) . unwrap ( ) as i32 ;
101+ let mut sec = self . sec + d_sec;
102+ let mut nsec = self . nsec + d_nsec;
97103 if nsec >= NSEC_PER_SEC {
98104 nsec -= NSEC_PER_SEC ;
99105 sec += 1 ;
@@ -102,15 +108,11 @@ impl Add<Timespec, Timespec> for Timespec {
102108 }
103109}
104110
105- impl Sub < Timespec , Timespec > for Timespec {
106- fn sub ( & self , other : & Timespec ) -> Timespec {
107- let mut sec = self . sec - other. sec ;
108- let mut nsec = self . nsec - other. nsec ;
109- if nsec < 0 {
110- nsec += NSEC_PER_SEC ;
111- sec -= 1 ;
112- }
113- Timespec :: new ( sec, nsec)
111+ impl Sub < Timespec , Duration > for Timespec {
112+ fn sub ( & self , other : & Timespec ) -> Duration {
113+ let sec = self . sec - other. sec ;
114+ let nsec = self . nsec - other. nsec ;
115+ Duration :: seconds ( sec) + Duration :: nanoseconds ( nsec as i64 )
114116 }
115117}
116118
@@ -1103,6 +1105,7 @@ mod tests {
11031105
11041106 use std:: f64;
11051107 use std:: result:: { Err , Ok } ;
1108+ use std:: time:: Duration ;
11061109 use self :: test:: Bencher ;
11071110
11081111 #[ cfg( windows) ]
@@ -1514,19 +1517,19 @@ mod tests {
15141517
15151518 fn test_timespec_add ( ) {
15161519 let a = Timespec :: new ( 1 , 2 ) ;
1517- let b = Timespec :: new ( 2 , 3 ) ;
1520+ let b = Duration :: seconds ( 2 ) + Duration :: nanoseconds ( 3 ) ;
15181521 let c = a + b;
15191522 assert_eq ! ( c. sec, 3 ) ;
15201523 assert_eq ! ( c. nsec, 5 ) ;
15211524
15221525 let p = Timespec :: new ( 1 , super :: NSEC_PER_SEC - 2 ) ;
1523- let q = Timespec :: new ( 2 , 2 ) ;
1526+ let q = Duration :: seconds ( 2 ) + Duration :: nanoseconds ( 2 ) ;
15241527 let r = p + q;
15251528 assert_eq ! ( r. sec, 4 ) ;
15261529 assert_eq ! ( r. nsec, 0 ) ;
15271530
15281531 let u = Timespec :: new ( 1 , super :: NSEC_PER_SEC - 2 ) ;
1529- let v = Timespec :: new ( 2 , 3 ) ;
1532+ let v = Duration :: seconds ( 2 ) + Duration :: nanoseconds ( 3 ) ;
15301533 let w = u + v;
15311534 assert_eq ! ( w. sec, 4 ) ;
15321535 assert_eq ! ( w. nsec, 1 ) ;
@@ -1536,20 +1539,17 @@ mod tests {
15361539 let a = Timespec :: new ( 2 , 3 ) ;
15371540 let b = Timespec :: new ( 1 , 2 ) ;
15381541 let c = a - b;
1539- assert_eq ! ( c. sec, 1 ) ;
1540- assert_eq ! ( c. nsec, 1 ) ;
1542+ assert_eq ! ( c. num_nanoseconds( ) , Some ( super :: NSEC_PER_SEC as i64 + 1 ) ) ;
15411543
15421544 let p = Timespec :: new ( 2 , 0 ) ;
15431545 let q = Timespec :: new ( 1 , 2 ) ;
15441546 let r = p - q;
1545- assert_eq ! ( r. sec, 0 ) ;
1546- assert_eq ! ( r. nsec, super :: NSEC_PER_SEC - 2 ) ;
1547+ assert_eq ! ( r. num_nanoseconds( ) , Some ( super :: NSEC_PER_SEC as i64 - 2 ) ) ;
15471548
15481549 let u = Timespec :: new ( 1 , 2 ) ;
15491550 let v = Timespec :: new ( 2 , 3 ) ;
15501551 let w = u - v;
1551- assert_eq ! ( w. sec, -2 ) ;
1552- assert_eq ! ( w. nsec, super :: NSEC_PER_SEC - 1 ) ;
1552+ assert_eq ! ( w. num_nanoseconds( ) , Some ( -super :: NSEC_PER_SEC as i64 - 1 ) ) ;
15531553 }
15541554
15551555 #[ test]
0 commit comments