1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
use std::cmp::Ordering; use std::fmt::{Display, Formatter, Debug}; use crate::LimitValue; use std::hash::Hash; #[derive(Debug, Clone, Hash, Eq, Ord)] pub struct IntervalLimit<T: Display + Clone + Hash + Ord> { closed: bool, lower: bool, value: LimitValue<T>, } impl<T: Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> PartialEq for IntervalLimit<T> { fn eq(&self, other: &Self) -> bool { self.partial_cmp(other) == Some(Ordering::Equal) } } impl<T: Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> PartialOrd for IntervalLimit<T> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { if self.value.is_limitless() && other.value.is_limitless() { if self.lower == other.lower { Some(Ordering::Equal) } else { self.lower_to_ordering(Some(Ordering::Less), Some(Ordering::Greater)) } } else if self.value.is_limitless() { self.lower_to_ordering(Some(Ordering::Less), Some(Ordering::Greater)) } else if other.value.is_limitless() { other.lower_to_ordering(Some(Ordering::Greater), Some(Ordering::Less)) } else if self.value == other.value { if self.lower && other.lower { if self.closed ^ other.closed { self.closed_to_ordering(Some(Ordering::Less), Some(Ordering::Greater)) } else { Some(Ordering::Equal) } } else if !self.lower && !other.lower { if self.closed ^ other.closed { self.closed_to_ordering(Some(Ordering::Greater), Some(Ordering::Less)) } else { Some(Ordering::Equal) } } else { self.lower_to_ordering(Some(Ordering::Less), Some(Ordering::Greater)) } } else { self.value.partial_cmp(&other.value) } } } impl<T: Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> IntervalLimit<T> { pub fn is_closed(&self) -> bool { self.closed } pub fn is_lower(&self) -> bool { self.lower } pub fn get_value(&self) -> &LimitValue<T> { &self.value } pub fn new(closed: bool, lower: bool, value: LimitValue<T>) -> Self { Self { closed: if value.is_limitless() { false } else { closed }, lower, value, } } pub fn lower(closed: bool, value: LimitValue<T>) -> Self { Self::new(closed, true, value) } pub fn upper(closed: bool, value: LimitValue<T>) -> Self { Self::new(closed, false, value) } fn lower_to_ordering<A>(&self, t: A, f: A) -> A { if self.lower { t } else { f } } fn closed_to_ordering<A>(&self, t: A, f: A) -> A { if self.closed { t } else { f } } pub fn is_infinity(&self) -> bool { self.value.is_limitless() } pub fn non_infinity(&self) -> bool { self.value.is_limit() } pub fn is_open(&self) -> bool { !self.closed } pub fn is_upper(&self) -> bool { !self.lower } } impl<T: Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> Display for IntervalLimit<T> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, "IntervalLimit({}, {}, {})", self.closed, self.lower, self.value ) } }