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
35impl PartialOrd for TimePoint {
36 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
37 Some(self.cmp(other))
38 }
39}
40
41impl Ord for TimePoint {
42 fn cmp(&self, other: &Self) -> Ordering {
43 self.epoch
44 .cmp(&other.epoch)
45 .then(self.immutable_file_number.cmp(&other.immutable_file_number))
46 .then(self.chain_point.cmp(&other.chain_point))
47 }
48}
49
50impl Display for TimePoint {
51 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52 write!(
53 f,
54 "TimePoint (epoch: {}, immutable_file_number: {}, chain_point: {})",
55 self.epoch, self.immutable_file_number, self.chain_point
56 )
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use std::cmp::Ordering;
63
64 use crate::entities::{BlockNumber, SlotNumber};
65
66 use super::*;
67
68 #[test]
69 fn time_point_ord_cmp_epochs_take_precedence_over_other_fields() {
70 let time_point1 = TimePoint {
71 epoch: Epoch(5),
72 immutable_file_number: 0,
73 chain_point: ChainPoint {
74 slot_number: SlotNumber(10),
75 block_number: BlockNumber(20),
76 block_hash: "hash1".to_string(),
77 },
78 };
79 let time_point2 = TimePoint {
80 epoch: Epoch(0),
81 immutable_file_number: 1,
82 chain_point: ChainPoint {
83 slot_number: SlotNumber(15),
84 block_number: BlockNumber(25),
85 block_hash: "hash2".to_string(),
86 },
87 };
88
89 assert_eq!(Ordering::Greater, time_point1.cmp(&time_point2));
90 }
91
92 #[test]
93 fn time_point_ord_cmp_if_epoch_equals_then_immutable_take_precedence_over_chain_point() {
94 let time_point1 = TimePoint {
95 epoch: Epoch(0),
96 immutable_file_number: 5,
97 chain_point: ChainPoint {
98 slot_number: SlotNumber(10),
99 block_number: BlockNumber(20),
100 block_hash: "hash1".to_string(),
101 },
102 };
103 let time_point2 = TimePoint {
104 epoch: Epoch(0),
105 immutable_file_number: 0,
106 chain_point: ChainPoint {
107 slot_number: SlotNumber(15),
108 block_number: BlockNumber(25),
109 block_hash: "hash2".to_string(),
110 },
111 };
112
113 assert_eq!(Ordering::Greater, time_point1.cmp(&time_point2));
114 }
115
116 #[test]
117 fn time_point_ord_cmp_if_epoch_and_immutables_equals_then_compare_over_chain_points() {
118 let time_point1 = TimePoint {
119 epoch: Epoch(0),
120 immutable_file_number: 0,
121 chain_point: ChainPoint {
122 slot_number: SlotNumber(10),
123 block_number: BlockNumber(20),
124 block_hash: "hash1".to_string(),
125 },
126 };
127 let time_point2 = TimePoint {
128 epoch: Epoch(0),
129 immutable_file_number: 0,
130 chain_point: ChainPoint {
131 slot_number: SlotNumber(15),
132 block_number: BlockNumber(25),
133 block_hash: "hash2".to_string(),
134 },
135 };
136
137 assert_eq!(Ordering::Less, time_point1.cmp(&time_point2));
138 }
139}