des_sim/primitive/time/
micro_step.rs1use std::fmt::{Display, Formatter};
9
10#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
12pub struct MicroStep(u64);
13
14impl Display for MicroStep {
15 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16 write!(f, "{}", self.0)
17 }
18}
19
20impl MicroStep {
21 #[must_use]
23 pub const fn zero() -> Self {
24 Self(0)
25 }
26
27 #[cfg(test)]
29 #[allow(dead_code)]
30 pub const fn new(value: u64) -> Self {
31 Self(value)
32 }
33
34 #[must_use]
40 pub const fn next(self) -> Self {
41 match self.0.checked_add(1) {
42 Some(val) => Self(val),
43 None => panic!("attempt to add with overflow"),
44 }
45 }
46
47 pub const fn value(&self) -> u64 {
49 self.0
50 }
51}
52
53#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
55pub struct MicroStepStatus {
56 current_micro_step: MicroStep,
57}
58
59impl MicroStepStatus {
60 pub(crate) fn new(current_micro_step: MicroStep) -> Self {
62 MicroStepStatus { current_micro_step }
63 }
64
65 pub(crate) fn initialize() -> Self {
67 MicroStepStatus {
68 current_micro_step: MicroStep::zero(),
69 }
70 }
71
72 pub fn current(&self) -> MicroStep {
74 self.current_micro_step
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn micro_step_zero() {
84 let step = MicroStep::zero();
85 assert_eq!(step.value(), 0);
86 }
87
88 #[test]
89 fn micro_step_new_and_value() {
90 let step = MicroStep::new(42);
91 assert_eq!(step.value(), 42);
92 }
93
94 #[test]
95 fn micro_step_display() {
96 let step = MicroStep::new(100);
97 assert_eq!(format!("{}", step), "100");
98 }
99
100 #[test]
101 fn micro_step_next() {
102 let step = MicroStep::zero();
103 let next_step = step.next();
104 assert_eq!(next_step.value(), 1);
105
106 let step_large = MicroStep::new(99);
107 assert_eq!(step_large.next().value(), 100);
108 }
109
110 #[test]
111 #[should_panic(expected = "attempt to add with overflow")]
112 fn micro_step_next_overflow_panic() {
113 let max_step = MicroStep::new(u64::MAX);
117 let _ = max_step.next();
118 }
119
120 #[test]
121 fn micro_step_comparison_and_ordering() {
122 let step1 = MicroStep::new(10);
123 let step2 = MicroStep::new(20);
124 let step3 = MicroStep::new(10);
125
126 assert!(step1 < step2);
127 assert!(step2 > step1);
128 assert!(step1 <= step3);
129 assert!(step1 >= step3);
130 assert_eq!(step1, step3);
131 assert_ne!(step1, step2);
132 }
133
134 #[test]
135 fn micro_step_status_initialize() {
136 let status = MicroStepStatus::initialize();
137 assert_eq!(status.current(), MicroStep::zero());
138 }
139
140 #[test]
141 fn micro_step_status_new_and_current() {
142 let step = MicroStep::new(5);
143 let status = MicroStepStatus::new(step);
144 assert_eq!(status.current(), step);
145 }
146
147 #[test]
148 fn micro_step_status_mutation_via_recreation() {
149 let status_initial = MicroStepStatus::initialize();
150 assert_eq!(status_initial.current().value(), 0);
151
152 let next_step = status_initial.current().next();
153 let status_next = MicroStepStatus::new(next_step);
154
155 assert_eq!(status_next.current().value(), 1);
156 assert_eq!(status_initial.current().value(), 0);
158 }
159}