#[forbid(deprecated_mode)];
-use core::cmp::Eq;
+use core::cmp::{Eq, Ord};
use core::int;
use core::libc::{c_char, c_int, c_long, size_t, time_t};
use core::i32;
use core::result::{Result, Ok, Err};
use core::str;
+const NSEC_PER_SEC: i32 = 1_000_000_000_i32;
+
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports]
#[auto_decode]
pub struct Timespec { sec: i64, nsec: i32 }
+/*
+ * Timespec assumes that pre-epoch Timespecs have negative sec and positive
+ * nsec fields. Darwin's and Linux's struct timespec functions handle pre-
+ * epoch timestamps using a "two steps back, one step forward" representation,
+ * though the man pages do not actually document this. For example, the time
+ * -1.2 seconds before the epoch is represented by `Timespec { sec: -2_i64,
+ * nsec: 800_000_000_i32 }`.
+ */
impl Timespec {
- static fn new(sec: i64, nsec: i32) -> Timespec {
+ static pure fn new(sec: i64, nsec: i32) -> Timespec {
+ assert nsec >= 0 && nsec < NSEC_PER_SEC;
Timespec { sec: sec, nsec: nsec }
}
}
pure fn ne(&self, other: &Timespec) -> bool { !self.eq(other) }
}
+impl Timespec : Ord {
+ pure fn lt(&self, other: &Timespec) -> bool {
+ self.sec < other.sec ||
+ (self.sec == other.sec && self.nsec < other.nsec)
+ }
+ pure fn le(&self, other: &Timespec) -> bool { !other.lt(self) }
+ pure fn ge(&self, other: &Timespec) -> bool { !self.lt(other) }
+ pure fn gt(&self, other: &Timespec) -> bool { !self.le(other) }
+}
+
/**
* Returns the current time as a `timespec` containing the seconds and
* nanoseconds since 1970-01-01T00:00:00Z.
None => Err(~"Invalid year")
},
'c' => {
- parse_type(s, pos, 'a', tm)
+ parse_type(s, pos, 'a', &mut *tm)
.chain(|pos| parse_char(s, pos, ' '))
- .chain(|pos| parse_type(s, pos, 'b', tm))
+ .chain(|pos| parse_type(s, pos, 'b', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
- .chain(|pos| parse_type(s, pos, 'e', tm))
+ .chain(|pos| parse_type(s, pos, 'e', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
- .chain(|pos| parse_type(s, pos, 'T', tm))
+ .chain(|pos| parse_type(s, pos, 'T', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
- .chain(|pos| parse_type(s, pos, 'Y', tm))
+ .chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
}
'D' | 'x' => {
- parse_type(s, pos, 'm', tm)
+ parse_type(s, pos, 'm', &mut *tm)
.chain(|pos| parse_char(s, pos, '/'))
- .chain(|pos| parse_type(s, pos, 'd', tm))
+ .chain(|pos| parse_type(s, pos, 'd', &mut *tm))
.chain(|pos| parse_char(s, pos, '/'))
- .chain(|pos| parse_type(s, pos, 'y', tm))
+ .chain(|pos| parse_type(s, pos, 'y', &mut *tm))
}
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
31_i32) {
None => Err(~"Invalid day of the month")
},
'F' => {
- parse_type(s, pos, 'Y', tm)
+ parse_type(s, pos, 'Y', &mut *tm)
.chain(|pos| parse_char(s, pos, '-'))
- .chain(|pos| parse_type(s, pos, 'm', tm))
+ .chain(|pos| parse_type(s, pos, 'm', &mut *tm))
.chain(|pos| parse_char(s, pos, '-'))
- .chain(|pos| parse_type(s, pos, 'd', tm))
+ .chain(|pos| parse_type(s, pos, 'd', &mut *tm))
}
'H' => {
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
None => Err(~"Invalid hour")
},
'R' => {
- parse_type(s, pos, 'H', tm)
+ parse_type(s, pos, 'H', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
- .chain(|pos| parse_type(s, pos, 'M', tm))
+ .chain(|pos| parse_type(s, pos, 'M', &mut *tm))
}
'r' => {
- parse_type(s, pos, 'I', tm)
+ parse_type(s, pos, 'I', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
- .chain(|pos| parse_type(s, pos, 'M', tm))
+ .chain(|pos| parse_type(s, pos, 'M', &mut *tm))
.chain(|pos| parse_char(s, pos, ':'))
- .chain(|pos| parse_type(s, pos, 'S', tm))
+ .chain(|pos| parse_type(s, pos, 'S', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
- .chain(|pos| parse_type(s, pos, 'p', tm))
+ .chain(|pos| parse_type(s, pos, 'p', &mut *tm))
}
'S' => {
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
}
//'s' {}
'T' | 'X' => {
- parse_type(s, pos, 'H', tm)
+ parse_type(s, pos, 'H', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
- .chain(|pos| parse_type(s, pos, 'M', tm))
+ .chain(|pos| parse_type(s, pos, 'M', &mut *tm))
.chain(|pos| parse_char(s, pos, ':'))
- .chain(|pos| parse_type(s, pos, 'S', tm))
+ .chain(|pos| parse_type(s, pos, 'S', &mut *tm))
}
't' => parse_char(s, pos, '\t'),
'u' => {
}
}
'v' => {
- parse_type(s, pos, 'e', tm)
+ parse_type(s, pos, 'e', &mut *tm)
.chain(|pos| parse_char(s, pos, '-'))
- .chain(|pos| parse_type(s, pos, 'b', tm))
+ .chain(|pos| parse_type(s, pos, 'b', &mut *tm))
.chain(|pos| parse_char(s, pos, '-'))
- .chain(|pos| parse_type(s, pos, 'Y', tm))
+ .chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
}
//'W' {}
'w' => {
assert utc.rfc822z() == ~"Fri, 13 Feb 2009 23:31:30 -0000";
assert utc.rfc3339() == ~"2009-02-13T23:31:30Z";
}
+
+ #[test]
+ fn test_timespec_eq_ord() {
+ use core::cmp::{eq, ge, gt, le, lt, ne};
+
+ let a = &Timespec::new(-2, 1);
+ let b = &Timespec::new(-1, 2);
+ let c = &Timespec::new(1, 2);
+ let d = &Timespec::new(2, 1);
+ let e = &Timespec::new(2, 1);
+
+ assert eq(d, e);
+ assert ne(c, e);
+
+ assert lt(a, b);
+ assert lt(b, c);
+ assert lt(c, d);
+
+ assert le(a, b);
+ assert le(b, c);
+ assert le(c, d);
+ assert le(d, e);
+ assert le(e, d);
+
+ assert ge(b, a);
+ assert ge(c, b);
+ assert ge(d, c);
+ assert ge(e, d);
+ assert ge(d, e);
+
+ assert gt(b, a);
+ assert gt(c, b);
+ assert gt(d, c);
+ }
}