mithril_client/cardano_database_client/
immutable_file_range.rs1use std::ops::RangeInclusive;
2
3use anyhow::anyhow;
4
5use mithril_common::{entities::ImmutableFileNumber, StdResult};
6
7#[derive(Debug, Eq, PartialEq)]
9pub enum ImmutableFileRange {
10 Full,
12
13 From(ImmutableFileNumber),
15
16 Range(ImmutableFileNumber, ImmutableFileNumber),
18
19 UpTo(ImmutableFileNumber),
21}
22
23impl ImmutableFileRange {
24 pub fn to_range_inclusive(
26 &self,
27 last_immutable_file_number: ImmutableFileNumber,
28 ) -> StdResult<RangeInclusive<ImmutableFileNumber>> {
29 const FIRST_IMMUTABLE_FILE_NUMBER: ImmutableFileNumber = 0;
30 let full_range = FIRST_IMMUTABLE_FILE_NUMBER..=last_immutable_file_number;
31
32 match self {
33 ImmutableFileRange::Full => Ok(full_range),
34 ImmutableFileRange::From(from) if full_range.contains(from) => {
35 Ok(*from..=last_immutable_file_number)
36 }
37 ImmutableFileRange::Range(from, to)
38 if full_range.contains(from)
39 && full_range.contains(to)
40 && !(*from..=*to).is_empty() =>
41 {
42 Ok(*from..=*to)
43 }
44 ImmutableFileRange::UpTo(to) if full_range.contains(to) => {
45 Ok(FIRST_IMMUTABLE_FILE_NUMBER..=*to)
46 }
47 _ => Err(anyhow!("Invalid immutable file range: {self:?}")),
48 }
49 }
50
51 pub fn length(&self, last_immutable_file_number: ImmutableFileNumber) -> u64 {
53 match self {
54 ImmutableFileRange::Full => last_immutable_file_number,
55 ImmutableFileRange::From(from) => last_immutable_file_number - from + 1,
56 ImmutableFileRange::Range(from, to) => to - from + 1,
57 ImmutableFileRange::UpTo(to) => *to,
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn to_range_inclusive_with_full() {
68 let immutable_file_range = ImmutableFileRange::Full;
69 let last_immutable_file_number = 10;
70
71 let result = immutable_file_range
72 .to_range_inclusive(last_immutable_file_number)
73 .unwrap();
74 assert_eq!(0..=10, result);
75 }
76
77 #[test]
78 fn to_range_inclusive_with_from() {
79 let immutable_file_range = ImmutableFileRange::From(5);
80
81 let last_immutable_file_number = 10;
82 let result = immutable_file_range
83 .to_range_inclusive(last_immutable_file_number)
84 .unwrap();
85 assert_eq!(5..=10, result);
86
87 let last_immutable_file_number = 3;
88 immutable_file_range
89 .to_range_inclusive(last_immutable_file_number)
90 .expect_err("should fail: given last immutable should be greater than range start");
91 }
92
93 #[test]
94 fn to_range_inclusive_with_range() {
95 let immutable_file_range = ImmutableFileRange::Range(5, 8);
96
97 let last_immutable_file_number = 10;
98 let result = immutable_file_range
99 .to_range_inclusive(last_immutable_file_number)
100 .unwrap();
101 assert_eq!(5..=8, result);
102
103 let last_immutable_file_number = 7;
104 immutable_file_range
105 .to_range_inclusive(last_immutable_file_number)
106 .expect_err(
107 "should fail: given last immutable should be greater or equal range max bound",
108 );
109
110 let immutable_file_range = ImmutableFileRange::Range(10, 8);
111 immutable_file_range
112 .to_range_inclusive(last_immutable_file_number)
113 .expect_err("should fail: range start should be lower than range end");
114 }
115
116 #[test]
117 fn to_range_inclusive_with_up_to() {
118 let immutable_file_range = ImmutableFileRange::UpTo(8);
119
120 let last_immutable_file_number = 10;
121 let result = immutable_file_range
122 .to_range_inclusive(last_immutable_file_number)
123 .unwrap();
124 assert_eq!(0..=8, result);
125
126 let last_immutable_file_number = 7;
127 immutable_file_range
128 .to_range_inclusive(last_immutable_file_number)
129 .expect_err(
130 "should fail: given last immutable should be greater or equal range max bound",
131 );
132 }
133
134 #[test]
135 fn length() {
136 let last_immutable_file_number = 10;
137
138 let immutable_file_range = ImmutableFileRange::Full;
139 assert_eq!(
140 last_immutable_file_number,
141 immutable_file_range.length(last_immutable_file_number)
142 );
143
144 let immutable_file_range = ImmutableFileRange::From(5);
145 assert_eq!(6, immutable_file_range.length(last_immutable_file_number));
146
147 let immutable_file_range = ImmutableFileRange::Range(5, 8);
148 assert_eq!(4, immutable_file_range.length(last_immutable_file_number));
149
150 let immutable_file_range = ImmutableFileRange::UpTo(8);
151 assert_eq!(8, immutable_file_range.length(last_immutable_file_number));
152 }
153}