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
|
||||
)]
|
||||
|
||||
pub use self::span::Span;
|
||||
|
||||
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