1use prost_types::{Duration, Timestamp};
2use time::{Duration as TimeDelta, OffsetDateTime};
3
4#[allow(clippy::unwrap_used)]
5pub fn datetime(seconds: i64, nanos: i32) -> OffsetDateTime {
6 OffsetDateTime::from_unix_timestamp(seconds)
7 .unwrap_or(OffsetDateTime::from_unix_timestamp(0).unwrap())
8 + TimeDelta::nanoseconds(nanos as i64)
9}
10
11pub fn duration(seconds: i64, nanos: i32) -> TimeDelta {
12 TimeDelta::new(seconds, nanos)
13}
14
15pub trait AsDateTime {
16 fn as_datetime(&self) -> OffsetDateTime;
17}
18
19impl AsDateTime for Timestamp {
20 #[allow(clippy::unwrap_used)]
21 fn as_datetime(&self) -> OffsetDateTime {
22 OffsetDateTime::from_unix_timestamp(self.seconds)
23 .unwrap_or(OffsetDateTime::from_unix_timestamp(0).unwrap())
24 + TimeDelta::nanoseconds(self.nanos as i64)
25 }
26}
27
28impl AsDateTime for &Timestamp {
29 fn as_datetime(&self) -> OffsetDateTime {
30 (*self).as_datetime()
31 }
32}
33
34pub trait AsDuration {
35 fn as_duration(&self) -> TimeDelta;
36}
37
38impl AsDuration for Duration {
39 fn as_duration(&self) -> TimeDelta {
40 TimeDelta::new(self.seconds, self.nanos)
41 }
42}
43
44impl AsDuration for Option<Duration> {
45 #[allow(clippy::unwrap_used)]
46 fn as_duration(&self) -> TimeDelta {
47 self.map(|d| d.as_duration()).unwrap_or_default()
48 }
49}
50
51pub trait VecExt<T> {
52 fn unique(&self) -> Vec<T>
53 where
54 T: Clone + PartialEq;
55}
56
57macro_rules! unique {
58 ($typ:ident) => {
59 impl VecExt<$typ> for Vec<$typ> {
60 fn unique(&self) -> Vec<$typ> {
61 let mut seen = Vec::new();
62 self.iter()
63 .filter(|x| {
64 if seen.contains(x) {
65 false
66 } else {
67 seen.push(x.clone());
68 true
69 }
70 })
71 .cloned()
72 .collect()
73 }
74 }
75 };
76}
77
78macro_rules! unique_to_bits {
79 ($typ:ident) => {
80 impl VecExt<$typ> for Vec<$typ> {
81 fn unique(&self) -> Vec<$typ> {
82 let mut seen = Vec::new();
83 self.iter()
84 .filter(|x| {
85 if seen.contains(&x.to_bits()) {
86 false
87 } else {
88 seen.push(x.to_bits());
89 true
90 }
91 })
92 .cloned()
93 .collect()
94 }
95 }
96 };
97}
98
99unique!(String);
100unique!(i32);
101unique!(i64);
102unique!(u32);
103unique!(u64);
104unique_to_bits!(f32);
105unique_to_bits!(f64);
106
107impl VecExt<Vec<u8>> for Vec<Vec<u8>> {
108 fn unique(&self) -> Vec<Vec<u8>> {
109 let mut seen = Vec::new();
110 self.iter()
111 .filter(|x| {
112 if seen.contains(x) {
113 false
114 } else {
115 #[allow(suspicious_double_ref_op)]
116 seen.push(x.clone());
117 true
118 }
119 })
120 .cloned()
121 .collect()
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn unique_float() {
131 let vals = vec![1.0, 2.0, 1.0, 3.0, 2.0];
132 let unique = vals.unique();
133 assert_eq!(unique, vec![1.0, 2.0, 3.0]);
134 }
135}