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
44pub 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    /// Returns `true` if `item` is contained in the range.
128    #[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    /// Returns `true` if the range contains no items.
141    ///
142    /// 仅有限区间可能为空。
143    #[inline]
144    pub fn is_empty(&self) -> bool {
145        matches!(self, Self::Finite(r) if r.start >= r.end)
146    }
147    
148    /// 判断当前区间是否完全包含另一个区间
149    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            // 无限区间 → 只要起始满足,就包含所有后续区间
155            (None, _) => true,
156            // 有限区间 → 当前结束 ≥ 另一个结束
157            (Some(self_end), Some(other_end)) => self_end >= other_end,
158            // 自身有限、另一个无限 → 无法包含
159            (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    /// 返回区间的大小
176    ///
177    /// 空区间返回Err <br>
178    /// 无限区间返回Ok(None) <br>
179    /// 有限区间返回Ok(Some)
180    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    /// 返回 `T::default..`
210    #[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            // 有限范围:迭代 Range<T>,到 end 停止
226            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            // 无限范围:一直迭代,永不停止
236            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}