1use rust_decimal::Decimal;
2use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
3use std::fmt::{self, Display};
4use std::ops::Add;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
7pub struct Time(Decimal);
8
9impl Time {
10 pub fn from_gps_seconds(seconds: f64) -> Self {
11 Time(Decimal::from_f64(seconds).expect("Failed to convert f64 to Decimal for Time."))
12 }
13
14 pub fn as_gps_seconds_f64(&self) -> f64 {
15 self.0
16 .to_f64()
17 .expect("Failed to convert Decimal to f64 for Time.")
18 }
19}
20
21impl Display for Time {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(f, "{}", self.0)
26 }
27}
28impl Add for Time {
29 type Output = Self;
30
31 fn add(self, other: Self) -> Self::Output {
32 Time(self.0 + other.0)
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn test_time_from_gps_seconds() {
42 let time = Time::from_gps_seconds(123456.789);
43 assert_eq!(time.as_gps_seconds_f64(), 123456.789);
44 }
45
46 #[test]
47 fn test_time_display() {
48 let time = Time::from_gps_seconds(98765.4321);
49 assert_eq!(format!("{}", time), "98765.4321");
50 }
51
52 #[test]
53 fn test_time_equality() {
54 let time1 = Time::from_gps_seconds(100.0);
55 let time2 = Time::from_gps_seconds(100.0);
56 let time3 = Time::from_gps_seconds(200.0);
57
58 assert_eq!(time1, time2);
59 assert_ne!(time1, time3);
60 assert!(time1 < time3);
61 }
62
63 #[test]
64 fn test_time_addition() {
65 let time1 = Time::from_gps_seconds(50.0);
66 let time2 = Time::from_gps_seconds(25.0);
67 let result = time1 + time2;
68
69 assert_eq!(result.as_gps_seconds_f64(), 75.0);
70 }
71
72 #[test]
73 fn test_time_ordering() {
74 let time1 = Time::from_gps_seconds(300.0);
75 let time2 = Time::from_gps_seconds(400.0);
76 let time3 = Time::from_gps_seconds(300.0);
77
78 assert!(time1 < time2);
79 assert!(time1 <= time3);
80 assert!(time2 > time1);
81 assert!(time2 >= time3);
82 }
83
84 #[test]
85 fn test_time_conversion() {
86 let time = Time::from_gps_seconds(123456.789);
87 let gps_seconds = time.as_gps_seconds_f64();
88 assert_eq!(gps_seconds, 123456.789);
89 }
90
91 #[test]
92 fn test_time_from_decimal() {
93 let decimal_time = Decimal::from_f64(123456.789).expect("Failed to create Decimal");
94 let time = Time(decimal_time);
95 assert_eq!(time.as_gps_seconds_f64(), 123456.789);
96 }
97
98 #[test]
99 #[allow(clippy::excessive_precision)]
100 fn test_time_creation_and_conversion() {
101 let gps_time = 1126259446.0;
102 let time_obj = Time::from_gps_seconds(gps_time);
103 assert_eq!(time_obj.as_gps_seconds_f64(), gps_time);
104
105 let precise_gps_time = 123456789.123456789;
106 let time_obj_precise = Time::from_gps_seconds(precise_gps_time);
107 assert_eq!(
111 time_obj_precise.0,
112 Decimal::from_f64(precise_gps_time).unwrap()
113 );
114 }
115}