Create a span type to use instead of the built-in range type
This commit is contained in:
parent
8cc6b9d415
commit
4a5b7321e8
@ -7,4 +7,8 @@
|
|||||||
unsafe_code
|
unsafe_code
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
pub use self::span::Span;
|
||||||
|
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
|
|
||||||
|
mod span;
|
||||||
|
90
onihime/src/span.rs
Normal file
90
onihime/src/span.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/// A (half-open) range bounded inclusively below and exclusively above
|
||||||
|
/// `(start..end)`.
|
||||||
|
///
|
||||||
|
/// The range `start..end` contains all values with `start <= x < end`. It is
|
||||||
|
/// empty if `start >= end`.
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Span {
|
||||||
|
/// The lower bound of the range (inclusive).
|
||||||
|
pub start: usize,
|
||||||
|
/// The upper bound of the range (exclusive).
|
||||||
|
pub end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Span {
|
||||||
|
/// Construct a new instance of a span.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(start: usize, end: usize) -> Self {
|
||||||
|
Self { start, end }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `item` is contained in the span.
|
||||||
|
#[must_use]
|
||||||
|
pub fn contains(&self, item: usize) -> bool {
|
||||||
|
self.start <= item && item < self.end
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the span contains no items.
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.start >= self.end
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extend the span's end bound to that of the provided span, if
|
||||||
|
/// `other.end > self.end`.
|
||||||
|
pub fn extend(&mut self, other: &Self) {
|
||||||
|
if other.end > self.end {
|
||||||
|
self.end = other.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::ops::Range<usize>> for Span {
|
||||||
|
fn from(range: std::ops::Range<usize>) -> Self {
|
||||||
|
Self::new(range.start, range.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Span> for std::ops::Range<usize> {
|
||||||
|
fn from(span: Span) -> Self {
|
||||||
|
span.start..span.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn span_equality() {
|
||||||
|
let a = Span::new(0, 0);
|
||||||
|
let b = Span::new(0, 1);
|
||||||
|
|
||||||
|
assert_eq!(a, a);
|
||||||
|
assert_ne!(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn span_contains() {
|
||||||
|
let s = Span::new(1, 3);
|
||||||
|
|
||||||
|
assert!(s.contains(1));
|
||||||
|
assert!(s.contains(2));
|
||||||
|
|
||||||
|
assert!(!s.contains(0));
|
||||||
|
assert!(!s.contains(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn span_extend() {
|
||||||
|
let mut a = Span::new(0, 5);
|
||||||
|
let b = Span::new(1, 10);
|
||||||
|
let c = Span::new(5, 6);
|
||||||
|
|
||||||
|
assert_eq!(a.end, 5);
|
||||||
|
a.extend(&b);
|
||||||
|
assert_eq!(a.end, 10);
|
||||||
|
a.extend(&c);
|
||||||
|
assert_eq!(a.end, 10);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user