feat: span works from the offset

This commit is contained in:
Jeremy Wall 2024-11-21 19:41:18 -05:00
parent 562a78eb3f
commit 025535f03c
4 changed files with 43 additions and 21 deletions

2
Cargo.lock generated
View File

@ -3,5 +3,5 @@
version = 3
[[package]]
name = "slice-cursor"
name = "slice-utils"
version = "0.1.0"

View File

@ -1,5 +1,5 @@
[package]
name = "slice-cursor"
name = "slice-utils"
version = "0.1.0"
edition = "2021"

View File

@ -42,6 +42,16 @@ pub trait Positioned: Offsetable {
fn column(&self) -> usize;
}
/// An input that can provide a span of a range of the input starting from the offset
pub trait Span<O> {
fn span<R: Into<SpanRange>>(&self, idx: R) -> O;
}
/// The interface for types that can peek ahead to the next item.
pub trait Peekable<O> {
fn peek_next(&self) -> Option<O>;
}
/// SpanRange encompasses the valid Ops::Range types for use with the Span trait.
pub enum SpanRange {
Range(std::ops::Range<usize>),
@ -74,16 +84,6 @@ impl From<std::ops::RangeFull> for SpanRange {
}
}
/// An input that can provide a span of a range of the input.
pub trait Span<O> {
fn span<R: Into<SpanRange>>(&self, idx: R) -> O;
}
/// The interface for types that can peek ahead to the next item.
pub trait Peekable<O> {
fn peek_next(&self) -> Option<O>;
}
/// A Cloneable Iterator that can report an offset as a count of processed Items.
pub trait Cursor: Iterator + Clone + Offsetable {
fn curr(&self) -> Self::Item;
@ -171,10 +171,10 @@ impl<'a, T: Debug + 'a> Cursor for SliceCursor<'a, T> {
impl<'a, T: Debug + 'a> Span<&'a [T]> for SliceCursor<'a, T> {
fn span<R: Into<SpanRange>>(&self, idx: R) -> &'a [T] {
match idx.into() {
SpanRange::Range(r) => self.source.index(r),
SpanRange::RangeTo(r) => self.source.index(r),
SpanRange::RangeFrom(r) => self.source.index(r),
SpanRange::RangeFull(r) => self.source.index(r),
SpanRange::Range(r) => self.source[self.offset..].index(r),
SpanRange::RangeTo(r) => self.source[self.offset..].index(r),
SpanRange::RangeFrom(r) => self.source[self.offset..].index(r),
SpanRange::RangeFull(r) => self.source[self.offset..].index(r),
}
}
}
@ -295,10 +295,10 @@ impl<'a> From<&'a str> for StrCursor<'a> {
impl<'a> Span<&'a str> for StrCursor<'a> {
fn span<R: Into<SpanRange>>(&self, idx: R) -> &'a str {
match idx.into() {
SpanRange::Range(r) => self.source.index(r),
SpanRange::RangeTo(r) => self.source.index(r),
SpanRange::RangeFrom(r) => self.source.index(r),
SpanRange::RangeFull(r) => self.source.index(r),
SpanRange::Range(r) => self.source[self.offset..].index(r),
SpanRange::RangeTo(r) => self.source[self.offset..].index(r),
SpanRange::RangeFrom(r) => self.source[self.offset..].index(r),
SpanRange::RangeFull(r) => self.source[self.offset..].index(r),
}
}
}

View File

@ -14,7 +14,7 @@
use super::{
SliceCursor, StrCursor,
Cursor, Offsetable,
Cursor, Offsetable, Span
};
#[test]
@ -80,3 +80,25 @@ fn test_str_iter() {
assert_eq!('o' as u8, out[1]);
assert_eq!('o' as u8, out[2]);
}
#[test]
fn test_str_span() {
let input_str = "foo bar quux";
let mut iter = StrCursor::new(input_str);
assert_eq!(0, iter.get_offset());
assert_eq!("foo", iter.span(0..3));
iter.next();
assert_eq!("oo", iter.span(0..2));
}
#[test]
fn test_slice_span() {
let input_str = "foo bar quux";
let mut iter = SliceCursor::new(input_str.as_bytes());
assert_eq!(0, iter.get_offset());
assert_eq!("foo".as_bytes(), iter.span(0..3));
iter.next();
assert_eq!("oo".as_bytes(), iter.span(0..2));
}