1use std::fmt;
2use std::ops::{Range as Fin, Sub};
3use std::ops::RangeFrom as Infin;
4use num_traits::{CheckedAdd, One};
5use thiserror::Error;
6
7#[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum Span<T>
45{
46 Finite(Fin<T>),
47 Infinite(Infin<T>),
48}
49
50impl<T> Span<T> {
51 #[inline]
52 pub fn from_finite(range: Fin<T>) -> Self {
53 Span::Finite(range)
54 }
55
56 #[inline]
57 pub fn from_infinite(range_from: Infin<T>) -> Self {
58 Span::Infinite(range_from)
59 }
60
61 #[inline]
62 pub fn new_finite(start: T, end: T) -> Self {Self::Finite(start..end)}
63
64 #[inline]
65 pub fn new_infinite(start: T) -> Self {Self::Infinite(start..)}
66
67 #[inline]
68 pub fn start(&self) -> &T {
69 match self {
70 Self::Finite(r) => &r.start,
71 Self::Infinite(r) => &r.start
72 }
73 }
74
75 #[inline]
76 pub fn end(&self) -> Option<&T> {
77 match self {
78 Self::Finite(r) => Some(&r.end),
79 Self::Infinite(_) => None
80 }
81 }
82
83 #[inline]
84 pub fn as_finite(&self) -> Option<&Fin<T>> {
85 match self {
86 Self::Finite(r) => Some(r),
87 Self::Infinite(_) => None,
88 }
89 }
90
91 #[inline]
92 pub fn as_infinite(&self) -> Option<&Infin<T>> {
93 match self {
94 Self::Infinite(r) => Some(r),
95 Self::Finite(_) => None,
96 }
97 }
98
99 #[inline]
100 pub fn into_finite(self) -> Option<Fin<T>> {
101 match self {
102 Self::Finite(r) => Some(r),
103 Self::Infinite(_) => None,
104 }
105 }
106
107 #[inline]
108 pub fn into_infinite(self) -> Option<Infin<T>> {
109 match self {
110 Self::Infinite(r) => Some(r),
111 Self::Finite(_) => None,
112 }
113 }
114
115 #[inline]
116 pub fn is_finite(&self) -> bool {
117 matches!(self, Self::Finite(_))
118 }
119
120 #[inline]
121 pub fn is_infinite(&self) -> bool {
122 matches!(self, Self::Infinite(_))
123 }
124}
125
126impl<T: PartialOrd> Span<T> {
127 #[inline]
129 pub fn contains<U>(&self, item: &U) -> bool
130 where
131 T: PartialOrd<U>,
132 U: ?Sized + PartialOrd<T>,
133 {
134 match self {
135 Self::Finite(r) => item >= &r.start && item < &r.end,
136 Self::Infinite(r) => item >= &r.start,
137 }
138 }
139
140 #[inline]
144 pub fn is_empty(&self) -> bool {
145 matches!(self, Self::Finite(r) if r.start >= r.end)
146 }
147
148 pub fn contains_span(&self, other: &Self) -> bool {
150 if self.start() > other.start() {
151 return false;
152 }
153 match (self.end(), other.end()) {
154 (None, _) => true,
156 (Some(self_end), Some(other_end)) => self_end >= other_end,
158 (Some(_), None) => false,
160 }
161 }
162}
163
164#[derive(Error, Debug, Clone, PartialEq, Eq)]
165pub enum SpanError {
166 #[error("有限区间为空,无法计算大小")]
167 EmptyFiniteSpan,
168}
169
170impl<T,O> Span<T>
171where
172 T: Sub<T, Output = O> + Copy + PartialOrd,
173 O: Sized,
174{
175 pub fn size(&self) -> Result<Option<O>,SpanError> {
181 match self.end() {
182 Some(end) => {
183 if self.is_empty() {
184 Err(SpanError::EmptyFiniteSpan)
185 } else {
186 Ok(Some( * end - * self.start()))
187 }
188 }
189 None => Ok(None),
190 }
191 }
192}
193
194impl<T> From<Fin<T>> for Span<T> {
195 #[inline]
196 fn from(value: Fin<T>) -> Self {
197 Self::Finite(value)
198 }
199}
200
201impl<T> From<Infin<T>> for Span<T> {
202 #[inline]
203 fn from(value: Infin<T>) -> Self {
204 Self::Infinite(value)
205 }
206}
207
208impl<T: Default> Default for Span<T> {
209 #[inline]
211 fn default() -> Self {
212 Self::new_infinite(T::default())
213 }
214}
215
216impl<T> Iterator for Span<T>
217where
218 T: One + CheckedAdd + PartialOrd + Copy,
219{
220 type Item = T;
221
222 #[inline]
223 fn next(&mut self) -> Option<Self::Item> {
224 match self {
225 Self::Finite(range) => {
227 let next_val = range.start.checked_add(&T::one())?;
228 if next_val < range.end {
229 range.start = next_val;
230 Some(next_val)
231 } else {
232 None
233 }
234 }
235 Self::Infinite(range) => {
237 let current = range.start;
238 range.start = current.checked_add(&T::one())?;
239 Some(current)
240 }
241 }
242 }
243}
244
245impl<T: fmt::Display> fmt::Display for Span<T> {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 match self {
248 Self::Finite(r) => write!(f, "[{}, {})", r.start, r.end),
249 Self::Infinite(r) => write!(f, "[{}, +∞)", r.start),
250 }
251 }
252}