Skip to main content

span_core/
span.rs

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/// 闭开区间 或 闭无限区间。<br>
8/// 即 `start..end` 或 `start..`。<br>
9/// 即 `[start,end)` 或 `[start,+∞)`。
10///
11/// 当为闭开区间时,`start <= i < end` 视为i包含于这个 `Span` <br>
12/// 当闭无限区间时,`start <= i` 视为i包含于这个 `Span`
13///
14/// `start >= end` 时视为空。
15///
16/// # Examples
17///
18/// 使用 `into` 来将 `Range` 和 `RangeFrom` 转换为 `Span` :
19///
20/// ```
21/// assert_eq!((3..5).into(), vault_utils::span::Span::new_finite(3,5));
22/// assert_eq!((3..).into(), vault_utils::span::Span::new_infinite(3));
23/// ```
24///
25/// 判断元素是否包含在区间内:
26/// ```
27/// let finite = Span::new_finite(2, 7);
28/// assert!(finite.contains(&3));
29/// assert!(!finite.contains(&7));
30///
31/// let infinite = Span::new_infinite(5);
32/// assert!(infinite.contains(&10));
33/// assert!(!infinite.contains(&3));
34/// ```
35///
36/// 判断区间是否为空:
37/// ```
38/// assert!(Span::new_finite(5, 3).is_empty());
39/// assert!(!Span::new_finite(3,5).is_empty());
40/// assert!(!Span::new_infinite(0).is_empty());
41/// assert!(!Span::new_infinite(usize::MAX).is_empty());
42/// ```
43#[derive(Clone, PartialEq, Eq, Hash, Debug)] // not Copy -- see #27186
44#[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    /// Returns `true` if `item` is contained in the range.
129    #[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    /// Returns `true` if the range contains no items.
142    ///
143    /// 仅有限区间可能为空。
144    #[inline]
145    pub fn is_empty(&self) -> bool {
146        matches!(self, Self::Finite(r) if r.start >= r.end)
147    }
148    
149    /// 判断当前区间是否完全包含另一个区间
150    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            // 无限区间 → 只要起始满足,就包含所有后续区间
156            (None, _) => true,
157            // 有限区间 → 当前结束 ≥ 另一个结束
158            (Some(self_end), Some(other_end)) => self_end >= other_end,
159            // 自身有限、另一个无限 → 无法包含
160            (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    /// 返回区间的大小
177    ///
178    /// 空区间返回Err <br>
179    /// 无限区间返回Ok(None) <br>
180    /// 有限区间返回Ok(Some)
181    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    /// 返回 `T::default..`
211    #[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            // 有限范围:迭代 Range<T>,到 end 停止
227            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            // 无限范围:一直迭代,永不停止
237            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}