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