Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_datime/src/clock/microsecond.rs

3.7 KiB, 21 runs

created by r1870400018:6321, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
2//! Anthropic Claude
3
4use crate::clock::{
5 PerSecondRated,
6 ClockNanoSecond,
7};
8
9use oxedyne_fe2o3_core::prelude::*;
10
11use std::fmt;
12
13/// A microsecond face over ClockNanoSecond: the arithmetic happens in
14/// nanoseconds and is converted back on the way out.
15///
16/// ```ignore
17/// use oxedyne_fe2o3_datime::clock::ClockMicroSecondres!();
18///
19/// let micros = ClockMicroSecond::new(500_000)?res!();
20/// assert_eq!(micros.of(), 500_000)res!();
21/// assert_eq!(micros.as_nanos().of(), 500_000_000)res!();
22/// ```
23#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
24pub struct ClockMicroSecond {
25 nanos: ClockNanoSecond,
26}
27
28impl ClockMicroSecond {
29 pub const MAX_VALUE: u32 = 999_999;
30 pub const NANOS_PER_MICRO: u32 = 1_000;
31
32 pub fn new(micros: u32) -> Outcome<Self> {
33 if micros > Self::MAX_VALUE {
34 return Err(err!(
35 "Microsecond {} is invalid, must be 0-{}",
36 micros,
37 Self::MAX_VALUE;
38 Invalid, Input
39 ));
40 }
41 let nanos = res!(ClockNanoSecond::from_micros(micros));
42 Ok(Self { nanos })
43 }
44
45 pub(crate) fn new_unchecked(micros: u32) -> Self {
46 let nanos = ClockNanoSecond::new_unchecked(micros * Self::NANOS_PER_MICRO);
47 Self { nanos }
48 }
49
50 pub fn of(&self) -> u32 {
51 self.nanos.to_micros()
52 }
53
54 pub fn as_nanos(&self) -> ClockNanoSecond {
55 self.nanos
56 }
57
58 /// Truncates the sub-microsecond part.
59 pub fn from_nanos(nanos: ClockNanoSecond) -> Self {
60 let micros = nanos.to_micros();
61 Self::new_unchecked(micros)
62 }
63
64 pub fn add_micros(&self, micros: u32) -> (Self, u32) {
65 let nanos_to_add = micros as u64 * Self::NANOS_PER_MICRO as u64;
66 let (new_nanos, second_carry) = self.nanos.add_nanos(nanos_to_add);
67 (Self::from_nanos(new_nanos), second_carry)
68 }
69
70 pub fn sub_micros(&self, micros: u32) -> (Self, u32) {
71 let nanos_to_sub = micros as u64 * Self::NANOS_PER_MICRO as u64;
72 let (new_nanos, second_borrow) = self.nanos.sub_nanos(nanos_to_sub);
73 (Self::from_nanos(new_nanos), second_borrow)
74 }
75}
76
77// Validation methods.
78impl ClockMicroSecond {
79 pub fn is_valid(&self) -> bool {
80 self.of() <= Self::MAX_VALUE
81 }
82}
83
84impl PerSecondRated for ClockMicroSecond {
85 fn per_second(&self) -> u64 {
86 1_000_000
87 }
88}
89
90impl fmt::Display for ClockMicroSecond {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "{:06}", self.of())
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_microsecond_creation() {
102 assert!(ClockMicroSecond::new(0).is_ok());
103 assert!(ClockMicroSecond::new(500_000).is_ok());
104 assert!(ClockMicroSecond::new(999_999).is_ok());
105 assert!(ClockMicroSecond::new(1_000_000).is_err());
106 }
107
108 #[test]
109 fn test_microsecond_conversions() {
110 let micros = ClockMicroSecond::new(123_456).unwrap();
111 assert_eq!(micros.of(), 123_456);
112 assert_eq!(micros.as_nanos().of(), 123_456_000);
113
114 let nanos = ClockNanoSecond::new(123_456_789).unwrap();
115 let micros = ClockMicroSecond::from_nanos(nanos);
116 assert_eq!(micros.of(), 123_456); // truncated
117 }
118
119 #[test]
120 fn test_microsecond_arithmetic() {
121 let micros = ClockMicroSecond::new(500_000).unwrap();
122 let (new_micros, carry) = micros.add_micros(300_000);
123 assert_eq!(new_micros.of(), 800_000);
124 assert_eq!(carry, 0);
125
126 let (new_micros, carry) = micros.add_micros(700_000);
127 assert_eq!(new_micros.of(), 200_000);
128 assert_eq!(carry, 1);
129
130 let (new_micros, borrow) = micros.sub_micros(200_000);
131 assert_eq!(new_micros.of(), 300_000);
132 assert_eq!(borrow, 0);
133
134 let (new_micros, borrow) = micros.sub_micros(700_000);
135 assert_eq!(new_micros.of(), 800_000);
136 assert_eq!(borrow, 1);
137 }
138
139 #[test]
140 fn test_per_second_rated() {
141 let micros = ClockMicroSecond::new(456_789).unwrap();
142 assert_eq!(micros.per_second(), 1_000_000);
143 }
144}