1use core::{
2 cmp::Ordering,
3 ops::{Add, AddAssign, Div, Mul, Sub},
4};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Copy, Debug, PartialEq, Default)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10pub struct Time {
11 s: f64,
12}
13
14impl Add for Time {
15 type Output = Self;
16 fn add(self, rhs: Self) -> Self::Output {
17 Self { s: self.s + rhs.s }
18 }
19}
20impl Sub for Time {
21 type Output = Self;
22 fn sub(self, rhs: Self) -> Self::Output {
23 Self { s: self.s - rhs.s }
24 }
25}
26impl AddAssign for Time {
27 fn add_assign(&mut self, rhs: Self) {
28 *self = Self { s: self.s + rhs.s }
29 }
30}
31impl Mul<Self> for Time {
32 type Output = Self;
33 fn mul(self, rhs: Self) -> Self::Output {
34 Self { s: self.s * rhs.s }
35 }
36}
37impl Mul<f64> for Time {
38 type Output = Self;
39 fn mul(self, rhs: f64) -> Self::Output {
40 Self { s: self.s * rhs }
41 }
42}
43impl Div<f64> for Time {
44 type Output = Self;
45
46 fn div(self, rhs: f64) -> Self::Output {
47 Self { s: self.s / rhs }
48 }
49}
50impl PartialOrd for Time {
51 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52 self.s.partial_cmp(&other.s)
53 }
54}
55
56impl Time {
57 pub fn from_seconds<T: Into<f64>>(val: T) -> Self {
58 Self { s: val.into() }
59 }
60 pub fn from_minutes<T: Into<f64>>(val: T) -> Self {
61 Self {
62 s: val.into() * 60.,
63 }
64 }
65 pub fn zero() -> Self {
66 Self { s: 0. }
67 }
68 pub fn as_seconds(&self) -> f64 {
69 self.s
70 }
71 pub fn as_minutes(&self) -> f64 {
72 self.s / 60.
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_from_seconds() {
82 let time = Time::from_seconds(120.0);
83 assert_eq!(time.as_seconds(), 120.0);
84 }
85
86 #[test]
87 fn test_from_minutes() {
88 let time = Time::from_minutes(2.0);
89 assert_eq!(time.as_seconds(), 120.0);
90 }
91
92 #[test]
93 fn test_as_seconds() {
94 let time = Time::from_minutes(2.);
95 assert_eq!(time.as_seconds(), 120.);
96 }
97
98 #[test]
99 fn test_as_minutes() {
100 let time = Time::from_seconds(30.0);
101 assert_eq!(time.as_minutes(), 0.5);
102 }
103
104 #[test]
105 fn test_into_time() {
106 Time::from_seconds(1.);
107 Time::from_seconds(1);
108 Time::from_minutes(1.);
109 Time::from_minutes(1);
110 }
111}