git2/
time.rs

1use std::cmp::Ordering;
2
3use libc::{c_char, c_int};
4
5use crate::raw;
6use crate::util::Binding;
7
8/// Time in a signature
9#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10pub struct Time {
11    raw: raw::git_time,
12}
13
14/// Time structure used in a git index entry.
15#[derive(Copy, Clone, Debug, Eq, PartialEq)]
16pub struct IndexTime {
17    raw: raw::git_index_time,
18}
19
20impl Time {
21    /// Creates a new time structure from its components.
22    pub fn new(time: i64, offset: i32) -> Time {
23        unsafe {
24            Binding::from_raw(raw::git_time {
25                time: time as raw::git_time_t,
26                offset: offset as c_int,
27                sign: if offset < 0 { '-' } else { '+' } as c_char,
28            })
29        }
30    }
31
32    /// Return the time, in seconds, from epoch
33    pub fn seconds(&self) -> i64 {
34        self.raw.time as i64
35    }
36
37    /// Return the timezone offset, in minutes
38    pub fn offset_minutes(&self) -> i32 {
39        self.raw.offset as i32
40    }
41
42    /// Return whether the offset was positive or negative. Primarily useful
43    /// in case the offset is specified as a negative zero.
44    pub fn sign(&self) -> char {
45        self.raw.sign as u8 as char
46    }
47}
48
49impl PartialOrd for Time {
50    fn partial_cmp(&self, other: &Time) -> Option<Ordering> {
51        Some(self.cmp(other))
52    }
53}
54
55impl Ord for Time {
56    fn cmp(&self, other: &Time) -> Ordering {
57        (self.raw.time, self.raw.offset).cmp(&(other.raw.time, other.raw.offset))
58    }
59}
60
61impl Binding for Time {
62    type Raw = raw::git_time;
63    unsafe fn from_raw(raw: raw::git_time) -> Time {
64        Time { raw }
65    }
66    fn raw(&self) -> raw::git_time {
67        self.raw
68    }
69}
70
71impl IndexTime {
72    /// Creates a new time structure from its components.
73    pub fn new(seconds: i32, nanoseconds: u32) -> IndexTime {
74        unsafe {
75            Binding::from_raw(raw::git_index_time {
76                seconds,
77                nanoseconds,
78            })
79        }
80    }
81
82    /// Returns the number of seconds in the second component of this time.
83    pub fn seconds(&self) -> i32 {
84        self.raw.seconds
85    }
86    /// Returns the nanosecond component of this time.
87    pub fn nanoseconds(&self) -> u32 {
88        self.raw.nanoseconds
89    }
90}
91
92impl Binding for IndexTime {
93    type Raw = raw::git_index_time;
94    unsafe fn from_raw(raw: raw::git_index_time) -> IndexTime {
95        IndexTime { raw }
96    }
97    fn raw(&self) -> raw::git_index_time {
98        self.raw
99    }
100}
101
102impl PartialOrd for IndexTime {
103    fn partial_cmp(&self, other: &IndexTime) -> Option<Ordering> {
104        Some(self.cmp(other))
105    }
106}
107
108impl Ord for IndexTime {
109    fn cmp(&self, other: &IndexTime) -> Ordering {
110        let me = (self.raw.seconds, self.raw.nanoseconds);
111        let other = (other.raw.seconds, other.raw.nanoseconds);
112        me.cmp(&other)
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use crate::Time;
119
120    #[test]
121    fn smoke() {
122        assert_eq!(Time::new(1608839587, -300).seconds(), 1608839587);
123        assert_eq!(Time::new(1608839587, -300).offset_minutes(), -300);
124        assert_eq!(Time::new(1608839587, -300).sign(), '-');
125        assert_eq!(Time::new(1608839587, 300).sign(), '+');
126    }
127}