1#![no_std]
2
3use core::{
4 cmp::{max, min},
5 ops::Range,
6};
7
8use heapless::Vec;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub struct CapacityError;
13
14impl core::fmt::Display for CapacityError {
15 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16 write!(f, "RangeSet capacity exceeded")
17 }
18}
19
20impl core::error::Error for CapacityError {}
21
22#[derive(Clone, Debug, PartialEq, Eq)]
24pub struct RangeInfo<T, K = ()>
25where
26 T: Ord + Copy,
27 K: core::fmt::Debug + Eq + Clone,
28{
29 pub range: Range<T>,
30 pub kind: K,
31}
32
33impl<T, K> RangeInfo<T, K>
34where
35 T: Ord + Copy,
36 K: core::fmt::Debug + Eq + Clone,
37{
38 pub fn new(range: Range<T>, kind: K) -> Self {
39 Self { range, kind }
40 }
41}
42
43#[derive(Clone, Debug)]
50pub struct RangeSet<T, K = (), const C: usize = 128>
51where
52 T: Ord + Copy,
53 K: core::fmt::Debug + Eq + Clone,
54{
55 elements: Vec<RangeInfo<T, K>, C>,
56}
57
58impl<T, K, const C: usize> Default for RangeSet<T, K, C>
59where
60 T: Ord + Copy,
61 K: core::fmt::Debug + Eq + Clone,
62{
63 fn default() -> Self {
64 Self {
65 elements: Vec::new(),
66 }
67 }
68}
69
70impl<T, K, const C: usize> RangeSet<T, K, C>
71where
72 T: Ord + Copy,
73 K: core::fmt::Debug + Eq + Clone,
74{
75 pub fn new() -> Self {
77 Self::default()
78 }
79
80 #[inline]
82 pub fn as_slice(&self) -> &[RangeInfo<T, K>] {
83 &self.elements
84 }
85
86 #[inline]
88 pub fn iter(&self) -> impl Iterator<Item = &RangeInfo<T, K>> {
89 self.elements.iter()
90 }
91
92 #[inline]
93 pub fn is_empty(&self) -> bool {
94 self.elements.is_empty()
95 }
96
97 #[inline]
98 pub fn len(&self) -> usize {
99 self.elements.len()
100 }
101
102 pub fn clear(&mut self) {
103 self.elements.clear();
104 }
105
106 pub fn add(&mut self, range: Range<T>, kind: K) -> Result<(), CapacityError> {
113 if range.start >= range.end {
114 return Ok(());
115 }
116
117 let mut out: Vec<RangeInfo<T, K>, C> = Vec::new();
119
120 for elem in self.elements.drain(..) {
121 if elem.range.end <= range.start || elem.range.start >= range.end {
123 out.push(elem).map_err(|_| CapacityError)?;
124 continue;
125 }
126
127 if elem.kind == kind {
129 out.push(elem).map_err(|_| CapacityError)?;
130 continue;
131 }
132
133 let has_left = elem.range.start < range.start;
135 let has_right = elem.range.end > range.end;
136
137 match (has_left, has_right) {
138 (true, true) => {
139 let left = elem.range.start..range.start;
141 if left.start < left.end {
142 out.push(RangeInfo::new(left, elem.kind.clone()))
143 .map_err(|_| CapacityError)?;
144 }
145 let right = range.end..elem.range.end;
146 if right.start < right.end {
147 out.push(RangeInfo::new(right, elem.kind))
148 .map_err(|_| CapacityError)?;
149 }
150 }
151 (true, false) => {
152 let left = elem.range.start..range.start;
154 if left.start < left.end {
155 out.push(RangeInfo::new(left, elem.kind))
156 .map_err(|_| CapacityError)?;
157 }
158 }
159 (false, true) => {
160 let right = range.end..elem.range.end;
162 if right.start < right.end {
163 out.push(RangeInfo::new(right, elem.kind))
164 .map_err(|_| CapacityError)?;
165 }
166 }
167 (false, false) => {
168 }
170 }
171 }
172
173 self.elements = out;
174
175 if self.elements.is_empty() {
177 self.elements
178 .push(RangeInfo::new(range, kind))
179 .map_err(|_| CapacityError)?;
180 return Ok(());
181 }
182
183 let insert_at = self
185 .elements
186 .binary_search_by(|e| {
187 if e.range.start < range.start {
188 core::cmp::Ordering::Less
189 } else {
190 core::cmp::Ordering::Greater
191 }
192 })
193 .unwrap_or_else(|pos| pos);
194
195 let mut merged_range = range;
196 let mut insert_at = insert_at;
197
198 while insert_at > 0 {
200 let left = &self.elements[insert_at - 1];
201 if left.range.end < merged_range.start || left.kind != kind {
202 break;
203 }
204 merged_range.start = min(merged_range.start, left.range.start);
205 merged_range.end = max(merged_range.end, left.range.end);
206 self.elements.remove(insert_at - 1);
207 insert_at -= 1;
208 }
209
210 while insert_at < self.elements.len() {
212 let right = &self.elements[insert_at];
213 if right.range.start > merged_range.end || right.kind != kind {
214 break;
215 }
216 merged_range.start = min(merged_range.start, right.range.start);
217 merged_range.end = max(merged_range.end, right.range.end);
218 self.elements.remove(insert_at);
219 }
220
221 self.elements
222 .insert(insert_at, RangeInfo::new(merged_range, kind))
223 .map_err(|_| CapacityError)?;
224 Ok(())
225 }
226
227 #[inline]
229 pub fn contains(&self, value: T) -> bool {
230 self.elements
232 .binary_search_by(|e| {
233 if e.range.end <= value {
234 core::cmp::Ordering::Less
235 } else if e.range.start > value {
236 core::cmp::Ordering::Greater
237 } else {
238 core::cmp::Ordering::Equal
239 }
240 })
241 .is_ok()
242 }
243
244 pub fn remove(&mut self, range: Range<T>) -> Result<(), CapacityError> {
252 if range.start >= range.end || self.elements.is_empty() {
253 return Ok(());
254 }
255
256 let mut out: Vec<RangeInfo<T, K>, C> = Vec::new();
257 for elem in self.elements.drain(..) {
258 if elem.range.end <= range.start || elem.range.start >= range.end {
260 out.push(elem).map_err(|_| CapacityError)?;
261 continue;
262 }
263
264 let has_left = elem.range.start < range.start;
265 let has_right = elem.range.end > range.end;
266
267 match (has_left, has_right) {
268 (true, true) => {
269 let left = elem.range.start..min(elem.range.end, range.start);
271 if left.start < left.end {
272 out.push(RangeInfo::new(left, elem.kind.clone()))
273 .map_err(|_| CapacityError)?;
274 }
275 let right = max(elem.range.start, range.end)..elem.range.end;
276 if right.start < right.end {
277 out.push(RangeInfo::new(right, elem.kind))
278 .map_err(|_| CapacityError)?;
279 }
280 }
281 (true, false) => {
282 let left = elem.range.start..min(elem.range.end, range.start);
284 if left.start < left.end {
285 out.push(RangeInfo::new(left, elem.kind))
286 .map_err(|_| CapacityError)?;
287 }
288 }
289 (false, true) => {
290 let right = max(elem.range.start, range.end)..elem.range.end;
292 if right.start < right.end {
293 out.push(RangeInfo::new(right, elem.kind))
294 .map_err(|_| CapacityError)?;
295 }
296 }
297 (false, false) => {
298 }
300 }
301 }
302 self.elements = out;
303 Ok(())
304 }
305
306 pub fn extend<I>(&mut self, ranges: I) -> Result<(), CapacityError>
312 where
313 I: IntoIterator<Item = (Range<T>, K)>,
314 {
315 for (r, kind) in ranges {
316 self.add(r, kind)?;
317 }
318 Ok(())
319 }
320}