1use crate::bound::Bound;
14
15#[cfg(feature="serde")] use serde::Deserialize;
17#[cfg(feature="serde")] use serde::Serialize;
18use few::Few;
19
20use std::cmp::Ordering;
22use std::str::FromStr;
23
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33#[cfg_attr(feature="serde", derive(Deserialize, Serialize))]
34pub enum RawInterval<T> {
35 Empty,
37 Point(T),
39 Open(T, T),
42 LeftOpen(T, T),
45 RightOpen(T, T),
48 Closed(T, T),
51 UpTo(T),
53 UpFrom(T),
55 To(T),
57 From(T),
59 Full,
61}
62
63impl<T> RawInterval<T> {
64 pub fn is_empty(&self) -> bool {
71 matches!(self, Self::Empty)
72 }
73
74 pub fn is_full(&self) -> bool {
78 matches!(self, Self::Full)
79 }
80
81 pub fn write_fmt_with<F>(&self,
86 f: &mut std::fmt::Formatter<'_>,
87 write_fn: F)
88 -> Result<(), std::fmt::Error>
89 where F: Fn(&T, &mut std::fmt::Formatter<'_>)
90 -> Result<(), std::fmt::Error>
91 {
92 use RawInterval::*;
93 match *self {
94 Empty => write!(f, "Ø"),
95 Point(ref p) => write_fn(p, f),
96 Open(ref l, ref r) => {
97 write!(f, "(")?;
98 write_fn(l, f)?;
99 write!(f, ",")?;
100 write_fn(r, f)?;
101 write!(f, ")")
102 },
103 LeftOpen(ref l, ref r) => {
104 write!(f, "(")?;
105 write_fn(l, f)?;
106 write!(f, ",")?;
107 write_fn(r, f)?;
108 write!(f, "]")
109 },
110 RightOpen(ref l, ref r) => {
111 write!(f, "[")?;
112 write_fn(l, f)?;
113 write!(f, ",")?;
114 write_fn(r, f)?;
115 write!(f, ")")
116 },
117 Closed(ref l, ref r) => {
118 write!(f, "[")?;
119 write_fn(l, f)?;
120 write!(f, ",")?;
121 write_fn(r, f)?;
122 write!(f, "]")
123 },
124 UpTo(ref p) => {
125 write!(f, "(-∞,")?;
126 write_fn(p, f)?;
127 write!(f, ")")
128 },
129 UpFrom(ref p) => {
130 write!(f, "(")?;
131 write_fn(p, f)?;
132 write!(f, ",∞)")
133 },
134 To(ref p) => {
135 write!(f, "(-∞,")?;
136 write_fn(p, f)?;
137 write!(f, "]")
138 },
139 From(ref p) => {
140 write!(f, "[")?;
141 write_fn(p, f)?;
142 write!(f, ",∞)")
143 },
144 Full => write!(f, "(-∞,∞)"),
145 }
146 }
147}
148
149impl<T> RawInterval<T> where T: Ord {
150 pub fn new(lower: Bound<T>, upper: Bound<T>) -> Self {
160 use Bound::*;
161 use RawInterval::*;
162 match (lower, upper) {
163 (Include(l), Include(u)) => Self::closed(l, u),
164 (Include(l), Exclude(u)) => Self::right_open(l, u),
165 (Include(l), Infinite) => From(l),
166 (Exclude(l), Include(u)) => Self::left_open(l, u),
167 (Exclude(l), Exclude(u)) => Self::open(l, u),
168 (Exclude(l), Infinite) => UpFrom(l),
169 (Infinite, Include(u)) => To(u),
170 (Infinite, Exclude(u)) => UpTo(u),
171 (Infinite, Infinite) => Full,
172 }
173 }
174
175 pub fn open(lower: T, upper: T) -> Self {
182 use RawInterval::*;
183 match T::cmp(&lower, &upper) {
184 Ordering::Less => Open(lower, upper),
185 _ => Empty,
186 }
187 }
188
189 pub fn left_open(lower: T, upper: T) -> Self {
196 use RawInterval::*;
197 match T::cmp(&lower, &upper) {
198 Ordering::Less => LeftOpen(lower, upper),
199 Ordering::Equal => Point(upper),
200 Ordering::Greater => Empty,
201 }
202 }
203
204 pub fn right_open(lower: T, upper: T) -> Self {
211 use RawInterval::*;
212 match T::cmp(&lower, &upper) {
213 Ordering::Less => RightOpen(lower, upper),
214 Ordering::Equal => Point(lower),
215 Ordering::Greater => Empty,
216 }
217 }
218
219 pub fn closed(lower: T, upper: T) -> Self {
226 use RawInterval::*;
227 match T::cmp(&lower, &upper) {
228 Ordering::Less => Closed(lower, upper),
229 Ordering::Equal => Point(lower),
230 Ordering::Greater => Empty,
231 }
232 }
233
234 pub fn contains(&self, point: &T) -> bool {
239 use RawInterval::*;
240 match *self {
241 Empty => false,
242 Point(ref p) => point == p,
243 Open(ref l, ref r) => point > l && point < r,
244 LeftOpen(ref l, ref r) => point > l && point <= r,
245 RightOpen(ref l, ref r) => point >= l && point < r,
246 Closed(ref l, ref r) => point >= l && point <= r,
247 UpTo(ref p) => point < p,
248 UpFrom(ref p) => point > p,
249 To(ref p) => point <= p,
250 From(ref p) => point >= p,
251 Full => true,
252 }
253 }
254
255 pub fn from_str_with<F, E>(s: &str, read_fn: F)
258 -> Result<Self, IntervalParseError<E>>
259 where F: Fn(&str) -> Result<T, E>
260 {
261 use RawInterval::*;
262 if s.starts_with("Ø") { return Ok(Empty); }
264 if let Ok(p) = read_fn(s) { return Ok(Point(p)); }
266
267 let (x, y) = s.split_once(',')
268 .ok_or(IntervalParseError::InvalidInterval)?;
269
270 let lb = if x.starts_with("(-∞") {
271 Bound::Infinite
272 } else if let Some(res) = x.strip_prefix('(') {
273 Bound::Exclude(read_fn(res)
274 .map_err(|e| IntervalParseError::InvalidValue(e))?)
275 } else if let Some(res) = x.strip_prefix('[') {
276 Bound::Include(read_fn(res)
277 .map_err(|e| IntervalParseError::InvalidValue(e))?)
278 } else {
279 return Err(IntervalParseError::InvalidInterval);
280 };
281
282 let ub = if y.ends_with("∞)") {
283 Bound::Infinite
284 } else if y.ends_with(')') {
285 let end = y.len() - 1;
286 Bound::Exclude(read_fn(&y[..end])
287 .map_err(|e| IntervalParseError::InvalidValue(e))?)
288 } else if y.ends_with(']') {
289 let end = y.len() - 1;
290 Bound::Include(read_fn(&y[..end])
291 .map_err(|e| IntervalParseError::InvalidValue(e))?)
292 } else {
293 return Err(IntervalParseError::InvalidInterval);
294 };
295
296 Ok(Self::new(lb, ub))
297 }
298}
299
300impl<T> RawInterval<T> where T: Clone {
301 pub fn bounds(&self) -> Option<(Bound<T>, Bound<T>)> {
307 use Bound::*;
308 use RawInterval::*;
309 Some(match *self {
310 Empty => return None,
311 Point(ref p) => (Include(p.clone()), Include(p.clone())),
312 Open(ref l, ref r) => (Exclude(l.clone()), Exclude(r.clone())),
313 LeftOpen(ref l, ref r) => (Exclude(l.clone()), Include(r.clone())),
314 RightOpen(ref l, ref r) => (Include(l.clone()), Exclude(r.clone())),
315 Closed(ref l, ref r) => (Include(l.clone()), Include(r.clone())),
316 UpTo(ref p) => (Infinite, Exclude(p.clone())),
317 UpFrom(ref p) => (Exclude(p.clone()), Infinite),
318 To(ref p) => (Infinite, Include(p.clone())),
319 From(ref p) => (Include(p.clone()), Infinite),
320 Full => (Infinite, Infinite),
321 })
322 }
323
324 pub fn lower_bound(&self) -> Option<Bound<T>> {
327 use Bound::*;
328 use RawInterval::*;
329 Some(match *self {
330 Empty => return None,
331 Point(ref p) => Include(p.clone()),
332 Open(ref l, _) => Exclude(l.clone()),
333 LeftOpen(ref l, _) => Exclude(l.clone()),
334 RightOpen(ref l, _) => Include(l.clone()),
335 Closed(ref l, _) => Include(l.clone()),
336 UpTo(_) => Infinite,
337 UpFrom(ref p) => Exclude(p.clone()),
338 To(_) => Infinite,
339 From(ref p) => Include(p.clone()),
340 Full => Infinite,
341 })
342 }
343
344 pub fn upper_bound(&self) -> Option<Bound<T>> {
347 use Bound::*;
348 use RawInterval::*;
349 Some(match *self {
350 Empty => return None,
351 Point(ref p) => Include(p.clone()),
352 Open(_, ref r) => Exclude(r.clone()),
353 LeftOpen(_, ref r) => Include(r.clone()),
354 RightOpen(_, ref r) => Exclude(r.clone()),
355 Closed(_, ref r) => Include(r.clone()),
356 UpTo(ref p) => Exclude(p.clone()),
357 UpFrom(_) => Infinite,
358 To(ref p) => Include(p.clone()),
359 From(_) => Infinite,
360 Full => Infinite,
361 })
362 }
363
364 pub fn infimum(&self) -> Option<T> {
366 use Bound::*;
367 match self.lower_bound() {
368 Some(Include(ref b)) => Some(b.clone()),
369 Some(Exclude(ref b)) => Some(b.clone()),
370 _ => None,
371 }
372 }
373
374 pub fn supremum(&self) -> Option<T> {
376 use Bound::*;
377 match self.upper_bound() {
378 Some(Include(ref b)) => Some(b.clone()),
379 Some(Exclude(ref b)) => Some(b.clone()),
380 _ => None,
381 }
382 }
383
384 pub fn extrema(&self) -> Option<(T, T)> {
387 match (self.infimum(), self.supremum()) {
388 (Some(l), Some(u)) => Some((l, u)),
389 _ => None,
390 }
391 }
392}
393
394impl<T> RawInterval<T> where T: Clone + std::ops::Sub<T> {
395 pub fn width(&self) -> Option<T::Output> {
397 self.extrema().map(|(l, r)| r - l)
398 }
399}
400
401impl<T> RawInterval<T> where T: Ord + Clone {
402 pub fn intersects(&self, other: &Self) -> bool {
407 !self.intersect(other).is_empty()
408 }
409
410 pub fn is_adjacent_to(&self, other: &Self) -> bool {
412 let a = match (self.lower_bound(), other.upper_bound()) {
413 (Some(lb), Some(ub)) => lb.is_union_adjacent_to(&ub),
414 _ => false,
415
416 };
417 let b = match (self.upper_bound(), other.lower_bound()) {
418 (Some(ub), Some(lb)) => lb.is_union_adjacent_to(&ub),
419 _ => false,
420 };
421 a || b
422 }
423
424 pub fn complement(&self) -> impl Iterator<Item=Self> {
430 use RawInterval::*;
431 match *self {
432 Empty => Few::One(Full),
433 Point(ref p) => Few::Two(UpTo(p.clone()), UpFrom(p.clone())),
434 Open(ref l, ref r) => Few::Two(To(l.clone()), From(r.clone())),
435 LeftOpen(ref l, ref r) => Few::Two(To(l.clone()), UpFrom(r.clone())),
436 RightOpen(ref l, ref r) => Few::Two(UpTo(l.clone()), From(r.clone())),
437 Closed(ref l, ref r) => Few::Two(UpTo(l.clone()), UpFrom(r.clone())),
438 UpTo(ref p) => Few::One(From(p.clone())),
439 UpFrom(ref p) => Few::One(To(p.clone())),
440 To(ref p) => Few::One(UpFrom(p.clone())),
441 From(ref p) => Few::One(UpTo(p.clone())),
442 Full => Few::Zero,
443 }
444 }
445
446 #[must_use]
449 pub fn intersect(&self, other: &Self) -> Self {
450 let lb = match (self.lower_bound(), other.lower_bound()) {
451 (Some(a), Some(b)) => a.greatest_intersect(&b),
452 _ => return Self::Empty, };
454
455 let ub = match (self.upper_bound(), other.upper_bound()) {
456 (Some(a), Some(b)) => a.least_intersect(&b),
457 _ => return Self::Empty, };
459
460 if lb.as_ref() == ub.as_ref() &&
461 ((lb.is_inclusive() && ub.is_exclusive()) ||
462 (lb.is_exclusive() && ub.is_inclusive()))
463 {
464 Self::Empty
465 } else {
466 Self::new(lb, ub)
467 }
468 }
469
470 pub fn union(&self, other: &Self) -> impl Iterator<Item=Self> {
473 match (self.is_empty(), other.is_empty()) {
474 (true, true) => Few::Zero,
475 (true, false) => Few::One(other.clone()),
476 (false, true) => Few::One(self.clone()),
477 (false, false) => {
478 if self.intersects(other) || self .is_adjacent_to(other) {
480 Few::One(self.enclose(other))
481 } else {
482 Few::Two(self.clone(), other.clone())
483 }
484 },
485 }
486 }
487
488 pub fn minus(&self, other: &Self) -> impl Iterator<Item=Self> {
491 other.complement()
492 .map(|i| self.intersect(&i))
493 .filter(|i| !i.is_empty())
494 .collect::<Vec<_>>()
495 .into_iter()
496 }
497
498 #[must_use]
501 pub fn enclose(&self, other: &Self) -> Self {
502 let lb = match (self.lower_bound(), other.lower_bound()) {
503 (Some(a), Some(b)) => a.least_union(&b),
504 (Some(a), None) => a,
505 (None, Some(b)) => b,
506 (None, None) => return Self::Empty, };
508
509 let ub = match (self.upper_bound(), other.upper_bound()) {
510 (Some(a), Some(b)) => a.greatest_union(&b),
511 (Some(a), None) => a,
512 (None, Some(b)) => b,
513 (None, None) => return Self::Empty, };
515
516 Self::new(lb, ub)
517 }
518
519 #[must_use]
522 pub fn closure(&self) -> Self {
523 use RawInterval::*;
524 match self {
525 Open(l, r) => Closed(l.clone(), r.clone()),
526 LeftOpen(l, r) => Closed(l.clone(), r.clone()),
527 RightOpen(l, r) => Closed(l.clone(), r.clone()),
528 UpTo(r) => To(r.clone()),
529 UpFrom(l) => From(l.clone()),
530 _ => self.clone(),
531 }
532 }
533
534 #[must_use]
539 pub fn enclose_all<I>(intervals: I) -> Self
540 where I: Iterator<Item=Self>
541 {
542 intervals.fold(Self::Full, |acc, i| acc.enclose(&i))
543 }
544
545 #[must_use]
547 pub fn intersect_all<I>(intervals: I) -> Self
548 where I: Iterator<Item=Self>
549 {
550 intervals.fold(Self::Full, |acc, i| acc.intersect(&i))
551 }
552
553 #[allow(clippy::option_if_let_else)] pub fn union_all<I>(intervals: I) -> impl Iterator<Item=Self>
556 where I: Iterator<Item=Self>
557 {
558 let mut it = intervals.filter(|i| !i.is_empty());
560
561 if let Some(start) = it.next() {
563 it.fold(vec![start], |mut prev, next| {
565 if next == Self::Full {
567 return vec![Self::Full];
568 }
569 let mut append = true;
570 for item in &mut prev {
571 if item.intersects(&next) || item .is_adjacent_to(&next) {
572 *item = item.enclose(&next);
573 append = false;
574 break;
575 }
576 }
577 if append {prev.push(next);}
578 prev
579 })
580 } else {
581 Vec::new()
582 }.into_iter()
583 }
584}
585
586impl<T> std::fmt::Display for RawInterval<T> where T: std::fmt::Display {
588 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
589 self.write_fmt_with(f, |p, f| write!(f, "{}", p))
590 }
591}
592
593impl<T> FromStr for RawInterval<T> where T: Ord + FromStr {
594 type Err = IntervalParseError<T::Err>;
595
596 fn from_str(s: &str) -> Result<Self, Self::Err> {
597 Self::from_str_with(s, T::from_str)
598 }
599}
600
601#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
603pub enum IntervalParseError<E> {
604 InvalidInterval,
606 InvalidValue(E),
608}
609
610
611impl<T> std::fmt::Binary for RawInterval<T>
612 where T: std::fmt::Binary
613{
614 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
615 -> Result<(), std::fmt::Error>
616 {
617 self.write_fmt_with(f, |p, f| std::fmt::Binary::fmt(p, f))
618 }
619}
620
621impl<T> std::fmt::Octal for RawInterval<T>
622 where T: std::fmt::Octal
623{
624 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
625 -> Result<(), std::fmt::Error>
626 {
627 self.write_fmt_with(f, |p, f| std::fmt::Octal::fmt(p, f))
628 }
629}
630
631impl<T> std::fmt::LowerHex for RawInterval<T>
632 where T: std::fmt::LowerHex
633{
634 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
635 -> Result<(), std::fmt::Error>
636 {
637 self.write_fmt_with(f, |p, f| std::fmt::LowerHex::fmt(p, f))
638 }
639}
640
641impl<T> std::fmt::UpperHex for RawInterval<T>
642 where T: std::fmt::UpperHex
643{
644 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
645 -> Result<(), std::fmt::Error>
646 {
647 self.write_fmt_with(f, |p, f| std::fmt::UpperHex::fmt(p, f))
648 }
649}
650
651
652impl<T> std::fmt::LowerExp for RawInterval<T>
653 where T: std::fmt::LowerExp
654{
655 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
656 -> Result<(), std::fmt::Error>
657 {
658 self.write_fmt_with(f, |p, f| std::fmt::LowerExp::fmt(p, f))
659 }
660}
661
662impl<T> std::fmt::UpperExp for RawInterval<T>
663 where T: std::fmt::UpperExp
664{
665 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
666 -> Result<(), std::fmt::Error>
667 {
668 self.write_fmt_with(f, |p, f| std::fmt::UpperExp::fmt(p, f))
669 }
670}
671
672impl<T> std::fmt::Pointer for RawInterval<T>
673 where T: std::fmt::Pointer
674{
675 fn fmt(&self, f: &mut std::fmt::Formatter<'_>)
676 -> Result<(), std::fmt::Error>
677 {
678 self.write_fmt_with(f, |p, f| std::fmt::Pointer::fmt(p, f))
679 }
680}