intervals_rs/
interval_seq.rs1use std::cmp::Ordering;
2use std::fmt::{Debug, Display};
3use std::hash::Hash;
4
5use crate::{Interval, IntervalLimit, to_ordering};
6
7#[derive(Clone)]
8pub enum Ordered {
9 UpperLower {
10 inverse_lower: bool,
11 inverse_upper: bool,
12 },
13 LowerUpper {
14 inverse_lower: bool,
15 inverse_upper: bool,
16 },
17}
18
19impl Ordered {
20 fn lower_factor(&self) -> i8 {
21 match self {
22 Ordered::UpperLower { inverse_lower, .. } => {
23 if *inverse_lower {
24 -1
25 } else {
26 1
27 }
28 }
29 Ordered::LowerUpper { inverse_lower, .. } => {
30 if *inverse_lower {
31 -1
32 } else {
33 1
34 }
35 }
36 }
37 }
38 fn upper_factor(&self) -> i8 {
39 match self {
40 Ordered::UpperLower { inverse_upper, .. } => {
41 if *inverse_upper {
42 -1
43 } else {
44 1
45 }
46 }
47 Ordered::LowerUpper { inverse_upper, .. } => {
48 if *inverse_upper {
49 -1
50 } else {
51 1
52 }
53 }
54 }
55 }
56
57 pub fn compare<T>(&self, e1: &Interval<T>, e2: &Interval<T>) -> Ordering
58 where
59 T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd,
60 {
61 match self {
62 Ordered::UpperLower { .. } => {
63 if e1.is_empty() && e2.is_empty() {
64 Ordering::Equal
65 } else if e1.is_empty() {
66 Ordering::Less
67 } else if e2.is_empty() {
68 Ordering::Greater
69 } else {
70 let upper_comparance = e1.upper.partial_cmp(&e2.upper).unwrap();
71 let lower_comparance = e1.lower.partial_cmp(&e2.lower).unwrap();
72 if upper_comparance != Ordering::Equal {
73 to_ordering(upper_comparance as i8 * self.upper_factor())
74 } else {
75 to_ordering(lower_comparance as i8 * self.lower_factor())
76 }
77 }
78 }
79 Ordered::LowerUpper { .. } => {
80 if e1.is_empty() && e2.is_empty() {
81 Ordering::Equal
82 } else if e1.is_empty() {
83 Ordering::Greater
84 } else if e2.is_empty() {
85 Ordering::Less
86 } else {
87 let upper_comparance = e1.upper.partial_cmp(&e2.upper).unwrap();
88 let lower_comparance = e1.lower.partial_cmp(&e2.lower).unwrap();
89 if upper_comparance != Ordering::Equal {
90 to_ordering(upper_comparance as i8 + self.lower_factor())
91 } else {
92 to_ordering(lower_comparance as i8 * self.upper_factor())
93 }
94 }
95 }
96 }
97 }
98}
99
100pub struct IntervalSeq<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> {
102 intervals: Vec<Interval<T>>,
104 ordered: Ordered,
106}
107
108impl<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> IntervalSeq<T> {
109 pub fn append(&mut self, value: &Interval<T>) {
113 self.intervals.push(value.clone());
114 }
115
116 pub fn is_empty(&self) -> bool {
120 self.intervals.is_empty()
121 }
122
123 pub fn empty() -> Self {
127 let intervals: Vec<Interval<T>> = vec![];
128 Self::new(intervals)
129 }
130
131 pub fn new(values: impl IntoIterator<Item = Interval<T>>) -> Self {
132 let mut intervals: Vec<Interval<T>> = vec![];
133 values.into_iter().for_each(|e| {
134 intervals.push(e);
135 });
136 Self {
137 intervals,
138 ordered: Ordered::UpperLower {
139 inverse_lower: true,
140 inverse_upper: false,
141 },
142 }
143 }
144
145 pub fn extent(&self) -> Interval<T> {
150 if self.intervals.is_empty() {
151 panic!("self.interval is empty!")
152 }
153 let first = self.intervals.get(0).unwrap();
154 if self.intervals.len() == 1 {
155 first.clone()
156 } else {
157 let mut lowers = self
158 .intervals
159 .iter()
160 .map(|e| e.lower.clone())
161 .collect::<Vec<IntervalLimit<T>>>();
162 lowers.sort_by(|a, b| a.partial_cmp(&b).unwrap());
163 let lower = lowers.get(0).unwrap();
164 let mut uppers = self
165 .intervals
166 .iter()
167 .map(|e| e.upper.clone())
168 .collect::<Vec<IntervalLimit<T>>>();
169 uppers.sort_by(|a, b| b.partial_cmp(&a).unwrap());
170 let upper = uppers.get(0).unwrap();
171 first.new_of_same_type(
172 lower.as_value().clone(),
173 lower.is_closed(),
174 upper.as_value().clone(),
175 upper.is_closed(),
176 )
177 }
178 }
179
180 pub fn gap(&self) -> Self {
188 if self.intervals.len() < 2 {
189 let values: Vec<Interval<T>> = vec![];
190 Self::new(values)
191 } else {
192 let mut values: Vec<Interval<T>> = vec![];
193 for i in 1usize..self.intervals.len() {
194 let left = &self.intervals[i - 1];
195 let right = &self.intervals[i];
196 let gap = left.gap(right);
197 if !gap.is_empty() {
198 values.push(gap);
199 }
200 }
201 Self::new(values)
202 }
203 }
204
205 pub fn intersections(&self) -> Self {
213 if self.intervals.len() < 2 {
214 let values: Vec<Interval<T>> = vec![];
215 Self::new(values)
216 } else {
217 let mut values: Vec<Interval<T>> = vec![];
218 for i in 1usize..self.intervals.len() {
219 let left = &self.intervals[i - 1];
220 let right = &self.intervals[i];
221 let gap = left.intersect(right);
222 if !gap.is_empty() {
223 values.push(gap);
224 }
225 }
226 Self::new(values)
227 }
228 }
229
230 pub fn iter(&mut self) -> impl Iterator<Item = &Interval<T>> {
232 let mut l = self.intervals.clone();
233 l.sort_by(|a, b| self.ordered.compare(a, b));
234 self.intervals = l;
235 self.intervals.iter()
236 }
237
238 pub fn into_iter(mut self) -> impl IntoIterator<Item = Interval<T>> {
240 let mut l = self.intervals.clone();
241 l.sort_by(|a, b| self.ordered.compare(a, b));
242 self.intervals = l;
243 self.intervals.into_iter()
244 }
245
246 pub fn len(&self) -> usize {
248 self.intervals.len()
249 }
250
251 pub fn get(&self, idx: usize) -> Option<&Interval<T>> {
253 self.intervals.get(idx)
254 }
255}