mithril_common/entities/
time_point.rs1use std::cmp::Ordering;
2use std::fmt::{Display, Formatter};
3
4use crate::entities::{ChainPoint, Epoch, ImmutableFileNumber};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct TimePoint {
10 pub epoch: Epoch,
12
13 pub immutable_file_number: ImmutableFileNumber,
15
16 pub chain_point: ChainPoint,
18}
19
20impl TimePoint {
21 pub fn new(
23 epoch: u64,
24 immutable_file_number: ImmutableFileNumber,
25 chain_point: ChainPoint,
26 ) -> TimePoint {
27 TimePoint {
28 epoch: Epoch(epoch),
29 immutable_file_number,
30 chain_point,
31 }
32 }
33
34 cfg_test_tools! {
35 pub fn dummy() -> Self {
37 Self::new(10, 100, ChainPoint::dummy())
38 }
39 }
40}
41
42impl PartialOrd for TimePoint {
43 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
44 Some(self.cmp(other))
45 }
46}
47
48impl Ord for TimePoint {
49 fn cmp(&self, other: &Self) -> Ordering {
50 self.epoch
51 .cmp(&other.epoch)
52 .then(self.immutable_file_number.cmp(&other.immutable_file_number))
53 .then(self.chain_point.cmp(&other.chain_point))
54 }
55}
56
57impl Display for TimePoint {
58 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59 write!(
60 f,
61 "TimePoint (epoch: {}, immutable_file_number: {}, chain_point: {})",
62 self.epoch, self.immutable_file_number, self.chain_point
63 )
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use std::cmp::Ordering;
70
71 use crate::entities::{BlockNumber, SlotNumber};
72
73 use super::*;
74
75 #[test]
76 fn time_point_ord_cmp_epochs_take_precedence_over_other_fields() {
77 let time_point1 = TimePoint {
78 epoch: Epoch(5),
79 immutable_file_number: 0,
80 chain_point: ChainPoint {
81 slot_number: SlotNumber(10),
82 block_number: BlockNumber(20),
83 block_hash: "hash1".to_string(),
84 },
85 };
86 let time_point2 = TimePoint {
87 epoch: Epoch(0),
88 immutable_file_number: 1,
89 chain_point: ChainPoint {
90 slot_number: SlotNumber(15),
91 block_number: BlockNumber(25),
92 block_hash: "hash2".to_string(),
93 },
94 };
95
96 assert_eq!(Ordering::Greater, time_point1.cmp(&time_point2));
97 }
98
99 #[test]
100 fn time_point_ord_cmp_if_epoch_equals_then_immutable_take_precedence_over_chain_point() {
101 let time_point1 = TimePoint {
102 epoch: Epoch(0),
103 immutable_file_number: 5,
104 chain_point: ChainPoint {
105 slot_number: SlotNumber(10),
106 block_number: BlockNumber(20),
107 block_hash: "hash1".to_string(),
108 },
109 };
110 let time_point2 = TimePoint {
111 epoch: Epoch(0),
112 immutable_file_number: 0,
113 chain_point: ChainPoint {
114 slot_number: SlotNumber(15),
115 block_number: BlockNumber(25),
116 block_hash: "hash2".to_string(),
117 },
118 };
119
120 assert_eq!(Ordering::Greater, time_point1.cmp(&time_point2));
121 }
122
123 #[test]
124 fn time_point_ord_cmp_if_epoch_and_immutables_equals_then_compare_over_chain_points() {
125 let time_point1 = TimePoint {
126 epoch: Epoch(0),
127 immutable_file_number: 0,
128 chain_point: ChainPoint {
129 slot_number: SlotNumber(10),
130 block_number: BlockNumber(20),
131 block_hash: "hash1".to_string(),
132 },
133 };
134 let time_point2 = TimePoint {
135 epoch: Epoch(0),
136 immutable_file_number: 0,
137 chain_point: ChainPoint {
138 slot_number: SlotNumber(15),
139 block_number: BlockNumber(25),
140 block_hash: "hash2".to_string(),
141 },
142 };
143
144 assert_eq!(Ordering::Less, time_point1.cmp(&time_point2));
145 }
146}