1#![no_std]
2
3use core::{
4 cmp::{max, min},
5 fmt::Debug,
6 ops::Range,
7};
8
9use heapless::Vec;
10
11#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
13pub enum RangeError<T>
14where
15 T: RangeInfo,
16{
17 #[error("RangeSet capacity exceeded")]
19 Capacity,
20 #[error("Range conflict: new {new:?} conflicts with existing non-overwritable {existing:?}")]
22 Conflict {
23 new: T,
25 existing: T,
27 },
28}
29
30pub trait RangeInfo: Debug + Clone + Sized {
31 type Kind: Debug + Eq + Clone;
32 type Type: Ord + Copy;
33 fn range(&self) -> Range<Self::Type>;
34 fn kind(&self) -> &Self::Kind;
35 fn overwritable(&self) -> bool;
36 fn clone_with_range(&self, range: Range<Self::Type>) -> Self;
37}
38
39#[derive(Clone, Debug)]
46pub struct RangeSet<T, const C: usize = 128>
47where
48 T: RangeInfo,
49{
50 elements: Vec<T, C>,
51}
52
53impl<T, const C: usize> Default for RangeSet<T, C>
54where
55 T: RangeInfo,
56{
57 fn default() -> Self {
58 Self::new()
59 }
60}
61
62impl<T, const C: usize> RangeSet<T, C>
63where
64 T: RangeInfo,
65{
66 pub const fn new() -> Self {
68 Self {
69 elements: Vec::new(),
70 }
71 }
72
73 #[inline]
75 fn ranges_overlap<T1: Ord + Copy>(r1: &Range<T1>, r2: &Range<T1>) -> bool {
76 !(r1.end <= r2.start || r1.start >= r2.end)
77 }
78
79 fn split_range(elem: &T, split_range: &Range<T::Type>) -> [Option<T>; 2] {
83 let elem_range = elem.range();
84 let has_left = elem_range.start < split_range.start;
85 let has_right = elem_range.end > split_range.end;
86
87 match (has_left, has_right) {
88 (true, true) => {
89 let left = elem_range.start..split_range.start;
91 let right = split_range.end..elem_range.end;
92 [
93 if left.start < left.end {
94 Some(elem.clone_with_range(left))
95 } else {
96 None
97 },
98 if right.start < right.end {
99 Some(elem.clone_with_range(right))
100 } else {
101 None
102 },
103 ]
104 }
105 (true, false) => {
106 let left = elem_range.start..min(elem_range.end, split_range.start);
108 [
109 if left.start < left.end {
110 Some(elem.clone_with_range(left))
111 } else {
112 None
113 },
114 None,
115 ]
116 }
117 (false, true) => {
118 let right = max(elem_range.start, split_range.end)..elem_range.end;
120 [
121 None,
122 if right.start < right.end {
123 Some(elem.clone_with_range(right))
124 } else {
125 None
126 },
127 ]
128 }
129 (false, false) => {
130 [None, None]
132 }
133 }
134 }
135
136 #[inline]
138 fn push_element(vec: &mut Vec<T, C>, elem: T) -> Result<(), RangeError<T>> {
139 vec.push(elem).map_err(|_| RangeError::Capacity)
140 }
141
142 #[inline]
144 pub fn as_slice(&self) -> &[T] {
145 &self.elements
146 }
147
148 #[inline]
150 pub fn iter(&self) -> impl Iterator<Item = &T> {
151 self.elements.iter()
152 }
153
154 #[inline]
155 pub fn is_empty(&self) -> bool {
156 self.elements.is_empty()
157 }
158
159 #[inline]
160 pub fn len(&self) -> usize {
161 self.elements.len()
162 }
163
164 pub fn clear(&mut self) {
165 self.elements.clear();
166 }
167
168 pub fn add(&mut self, new_info: T) -> Result<(), RangeError<T>> {
178 if new_info.range().start >= new_info.range().end {
179 return Ok(());
180 }
181
182 for elem in &self.elements {
183 if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
185 continue;
186 }
187
188 if elem.kind() == new_info.kind() {
190 continue;
191 }
192
193 if !elem.overwritable() {
195 return Err(RangeError::Conflict {
197 new: new_info,
198 existing: elem.clone(),
199 });
200 }
201 }
202
203 let mut out: Vec<T, C> = Vec::new();
205
206 for elem in self.elements.drain(..) {
207 if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
209 Self::push_element(&mut out, elem)?;
210 continue;
211 }
212
213 if elem.kind() == new_info.kind() {
215 Self::push_element(&mut out, elem)?;
216 continue;
217 }
218
219 let split_parts = Self::split_range(&elem, &new_info.range());
221 for part in split_parts.iter().flatten() {
222 Self::push_element(&mut out, part.clone())?;
223 }
224 }
225
226 self.elements = out;
227
228 if self.elements.is_empty() {
230 Self::push_element(&mut self.elements, new_info.clone())?;
231 return Ok(());
232 }
233
234 let insert_at = self
236 .elements
237 .binary_search_by(|e| {
238 if e.range().start < new_info.range().start {
239 core::cmp::Ordering::Less
240 } else {
241 core::cmp::Ordering::Greater
242 }
243 })
244 .unwrap_or_else(|pos| pos);
245
246 let mut merged_range = new_info.range().clone();
247 let mut insert_at = insert_at;
248
249 while insert_at > 0 {
251 let left = &self.elements[insert_at - 1];
252 if left.range().end < merged_range.start || left.kind() != new_info.kind() {
253 break;
254 }
255 merged_range.start = min(merged_range.start, left.range().start);
256 merged_range.end = max(merged_range.end, left.range().end);
257 self.elements.remove(insert_at - 1);
258 insert_at -= 1;
259 }
260
261 while insert_at < self.elements.len() {
263 let right = &self.elements[insert_at];
264 if right.range().start > merged_range.end || right.kind() != new_info.kind() {
265 break;
266 }
267 merged_range.start = min(merged_range.start, right.range().start);
268 merged_range.end = max(merged_range.end, right.range().end);
269 self.elements.remove(insert_at);
270 }
271
272 self.elements
273 .insert(insert_at, new_info.clone_with_range(merged_range))
274 .map_err(|_| RangeError::Capacity)?;
275 Ok(())
276 }
277
278 #[inline]
280 pub fn contains(&self, value: T::Type) -> bool {
281 self.elements
283 .binary_search_by(|e| {
284 if e.range().end <= value {
285 core::cmp::Ordering::Less
286 } else if e.range().start > value {
287 core::cmp::Ordering::Greater
288 } else {
289 core::cmp::Ordering::Equal
290 }
291 })
292 .is_ok()
293 }
294
295 pub fn remove(&mut self, range: Range<T::Type>) -> Result<(), RangeError<T>> {
303 if range.start >= range.end || self.elements.is_empty() {
304 return Ok(());
305 }
306
307 let mut out: Vec<T, C> = Vec::new();
308 for elem in self.elements.drain(..) {
309 if !Self::ranges_overlap(&elem.range(), &range) {
311 Self::push_element(&mut out, elem)?;
312 continue;
313 }
314
315 let split_parts = Self::split_range(&elem, &range);
317 for part in split_parts.iter().flatten() {
318 Self::push_element(&mut out, part.clone())?;
319 }
320 }
321 self.elements = out;
322 Ok(())
323 }
324
325 pub fn extend<I>(&mut self, ranges: I) -> Result<(), RangeError<T>>
331 where
332 I: IntoIterator<Item = T>,
333 {
334 for v in ranges {
335 self.add(v)?;
336 }
337 Ok(())
338 }
339}