-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,26 @@ | ||
use std::{fmt, ops}; | ||
use libc::{time_t, suseconds_t}; | ||
|
||
#[repr(C)] | ||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] | ||
pub struct TimeVal { | ||
pub tv_sec: time_t, | ||
pub tv_usec: suseconds_t, | ||
} | ||
use libc::{time_t, suseconds_t, timeval}; | ||
|
||
const MICROS_PER_SEC: i64 = 1_000_000; | ||
const SECS_PER_MINUTE: i64 = 60; | ||
const SECS_PER_HOUR: i64 = 3600; | ||
|
||
#[cfg(target_pointer_width = "64")] | ||
const MAX_SECONDS: i64 = (::std::i64::MAX / MICROS_PER_SEC) - 1; | ||
#[derive(Clone, Copy)] | ||
pub struct TimeVal { | ||
pub val: timeval, | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
#[cfg(target_pointer_width = "32")] | ||
const MAX_SECONDS: i64 = ::std::isize::MAX as i64; | ||
impl AsRef<timeval> for TimeVal { | ||
fn as_ref(&self) -> &timeval { | ||
&self.val | ||
} | ||
} | ||
|
||
const MIN_SECONDS: i64 = -MAX_SECONDS; | ||
impl AsMut<timeval> for TimeVal { | ||
fn as_mut(&mut self) -> &mut timeval { | ||
&mut self.val | ||
} | ||
} | ||
|
||
impl TimeVal { | ||
#[inline] | ||
|
@@ -44,8 +46,8 @@ impl TimeVal { | |
|
||
#[inline] | ||
pub fn seconds(seconds: i64) -> TimeVal { | ||
assert!(seconds >= MIN_SECONDS && seconds <= MAX_SECONDS, "TimeVal out of bounds; seconds={}", seconds); | ||
TimeVal { tv_sec: seconds as time_t, tv_usec: 0 } | ||
assert!(seconds >= time_t::min_value() && seconds <= time_t::max_value(), "TimeVal out of bounds; seconds={}", seconds); | ||
TimeVal { val: timeval { tv_sec: seconds as time_t, tv_usec: 0 } } | ||
} | ||
|
||
#[inline] | ||
|
@@ -60,8 +62,8 @@ impl TimeVal { | |
#[inline] | ||
pub fn microseconds(microseconds: i64) -> TimeVal { | ||
let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); | ||
assert!(secs >= MIN_SECONDS && secs <= MAX_SECONDS, "TimeVal out of bounds"); | ||
TimeVal { tv_sec: secs as time_t, tv_usec: micros as suseconds_t } | ||
assert!(secs >= time_t::min_value() && secs <= time_t::max_value(), "TimeVal out of bounds; seconds={}", secs); | ||
TimeVal { val: timeval { tv_sec: secs as time_t, tv_usec: micros as suseconds_t } } | ||
} | ||
|
||
pub fn num_hours(&self) -> i64 { | ||
|
@@ -73,10 +75,10 @@ impl TimeVal { | |
} | ||
|
||
pub fn num_seconds(&self) -> i64 { | ||
if self.tv_sec < 0 && self.tv_usec > 0 { | ||
(self.tv_sec + 1) as i64 | ||
if self.val.tv_sec < 0 && self.val.tv_usec > 0 { | ||
(self.val.tv_sec + 1) as i64 | ||
} else { | ||
self.tv_sec as i64 | ||
self.val.tv_sec as i64 | ||
} | ||
} | ||
|
||
|
@@ -91,10 +93,10 @@ impl TimeVal { | |
} | ||
|
||
fn micros_mod_sec(&self) -> suseconds_t { | ||
if self.tv_sec < 0 && self.tv_usec > 0 { | ||
self.tv_usec - MICROS_PER_SEC as suseconds_t | ||
if self.val.tv_sec < 0 && self.val.tv_usec > 0 { | ||
self.val.tv_usec - MICROS_PER_SEC as suseconds_t | ||
} else { | ||
self.tv_usec | ||
self.val.tv_usec | ||
} | ||
} | ||
} | ||
|
@@ -147,32 +149,40 @@ impl ops::Div<i32> for TimeVal { | |
|
||
impl fmt::Display for TimeVal { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
let (abs, sign) = if self.tv_sec < 0 { | ||
let (abs, sign) = if self.val.tv_sec < 0 { | ||
(-*self, "-") | ||
} else { | ||
(*self, "") | ||
}; | ||
|
||
let sec = abs.tv_sec; | ||
let sec = abs.val.tv_sec; | ||
|
||
try!(write!(f, "{}", sign)); | ||
|
||
if abs.tv_usec == 0 { | ||
if abs.tv_sec == 1 { | ||
if abs.val.tv_usec == 0 { | ||
if abs.val.tv_sec == 1 { | ||
try!(write!(f, "{} second", sec)); | ||
} else { | ||
try!(write!(f, "{} seconds", sec)); | ||
} | ||
} else if abs.tv_usec % 1000 == 0 { | ||
try!(write!(f, "{}.{:03} seconds", sec, abs.tv_usec / 1000)); | ||
} else if abs.val.tv_usec % 1_000 == 0 { | ||
try!(write!(f, "{}.{:03} seconds", sec, abs.val.tv_usec / 1_000)); | ||
} else { | ||
try!(write!(f, "{}.{:06} seconds", sec, abs.tv_usec)); | ||
try!(write!(f, "{}.{:06} seconds", sec, abs.val.tv_usec)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl PartialEq for TimeVal { | ||
fn eq(&self, rhs: &TimeVal) -> bool { | ||
self.val.tv_sec == rhs.val.tv_sec && self.val.tv_usec == rhs.val.tv_usec | ||
} | ||
} | ||
|
||
impl Eq for TimeVal { } | ||
|
||
#[inline] | ||
fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) { | ||
(div_floor_64(this, other), mod_floor_64(this, other)) | ||
|
@@ -208,17 +218,16 @@ mod test { | |
#[test] | ||
pub fn test_time_val() { | ||
assert!(TimeVal::seconds(1) != TimeVal::zero()); | ||
assert_eq!(TimeVal::seconds(1) + TimeVal::seconds(2), TimeVal::seconds(3)); | ||
assert_eq!(TimeVal::minutes(3) + TimeVal::seconds(2), | ||
TimeVal::seconds(182)); | ||
assert!(TimeVal::seconds(1) + TimeVal::seconds(2) == TimeVal::seconds(3)); | ||
assert!(TimeVal::minutes(3) + TimeVal::seconds(2) == TimeVal::seconds(182)); | ||
} | ||
|
||
#[test] | ||
pub fn test_time_val_neg() { | ||
let a = TimeVal::seconds(1) + TimeVal::microseconds(123); | ||
let b = TimeVal::seconds(-1) + TimeVal::microseconds(-123); | ||
|
||
assert_eq!(a, -b); | ||
assert!(a == -b); | ||
This comment has been minimized.
Sorry, something went wrong.
kamalmarhubi
|
||
} | ||
|
||
#[test] | ||
|
1 comment
on commit c4a38ec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not know about this module before, and I don't like it! But the changes make sense to me. :-)
can you use the newtype pattern here: