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