1use std::convert::TryInto;
2use std::ops::Add;
3use std::ops::AddAssign;
4use std::ops::Sub;
5use std::ops::SubAssign;
6
7use crate::Timestamp;
8
9impl Add<std::time::Duration> for Timestamp {
10 type Output = Self;
11
12 fn add(self, other: std::time::Duration) -> Timestamp {
14 let s: i64 = other.as_secs() as i64;
15 Timestamp::new(self.seconds + s, self.nanos + other.subsec_nanos())
16 }
17}
18
19impl AddAssign<std::time::Duration> for Timestamp {
20 fn add_assign(&mut self, other: std::time::Duration) {
22 let delta: i64 = other.as_secs() as i64;
23 self.seconds += delta;
24 self.nanos += other.subsec_nanos();
25 while self.nanos >= 1_000_000_000 {
26 self.seconds += 1;
27 self.nanos -= 1_000_000_000;
28 }
29 }
30}
31
32impl Sub<std::time::Duration> for Timestamp {
33 type Output = Self;
34
35 fn sub(self, other: std::time::Duration) -> Timestamp {
37 let other_sec: i64 = other.as_secs().try_into().unwrap();
38 if other.subsec_nanos() > self.nanos {
39 return Timestamp::new(
40 self.seconds - other_sec - 1,
41 self.nanos + 1_000_000_000 - other.subsec_nanos(),
42 );
43 }
44 Timestamp::new(self.seconds - other_sec, self.nanos - other.subsec_nanos())
45 }
46}
47
48impl SubAssign<std::time::Duration> for Timestamp {
49 fn sub_assign(&mut self, other: std::time::Duration) {
51 let delta: i64 = other.as_secs().try_into().unwrap();
52 self.seconds -= delta;
53 if other.subsec_nanos() > self.nanos {
54 self.seconds -= 1;
55 self.nanos += 1_000_000_000;
56 }
57 self.nanos -= other.subsec_nanos();
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_add() {
67 let ts = Timestamp::new(1335020400, 0);
68 let dur = std::time::Duration::new(86400, 0);
69 assert_eq!(ts + dur, Timestamp::new(1335020400 + 86400, 0));
70 }
71
72 #[test]
73 fn test_add_assign() {
74 let mut ts = Timestamp::new(1335020400, 0);
75 ts += std::time::Duration::new(86400, 0);
76 assert_eq!(ts, Timestamp::new(1335020400 + 86400, 0));
77 }
78
79 #[test]
80 fn test_add_assign_nano_overflow() {
81 let mut ts = Timestamp::new(1335020400, 500_000_000);
82 ts += std::time::Duration::new(0, 750_000_000);
83 assert_eq!(ts.seconds, 1335020401);
84 assert_eq!(ts.nanos, 250_000_000);
85 }
86
87 #[test]
88 fn test_sub() {
89 let ts = Timestamp::new(1335020400, 0);
90 let dur = std::time::Duration::new(86400, 0);
91 assert_eq!(ts - dur, Timestamp::new(1335020400 - 86400, 0));
92 }
93
94 #[test]
95 fn test_sub_nano_overflow() {
96 let ts = Timestamp::new(1335020400, 500_000_000) - std::time::Duration::new(0, 750_000_000);
97 assert_eq!(ts.seconds, 1335020399);
98 assert_eq!(ts.nanos, 750_000_000);
99 }
100
101 #[test]
102 fn test_sub_assign() {
103 let mut ts = Timestamp::new(1335020400, 0);
104 ts -= std::time::Duration::new(86400, 0);
105 assert_eq!(ts.seconds, 1335020400 - 86400);
106 assert_eq!(ts.nanos, 0);
107 }
108
109 #[test]
110 fn test_sub_assign_nano_overflow() {
111 let mut ts = Timestamp::new(1335020400, 500_000_000);
112 ts -= std::time::Duration::new(0, 750_000_000);
113 assert_eq!(ts.seconds, 1335020399);
114 assert_eq!(ts.nanos, 750_000_000);
115 }
116}