From 025535f03c843761243ba96c6d6baa71e5697dcd Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Thu, 21 Nov 2024 19:41:18 -0500 Subject: [PATCH] feat: span works from the offset --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/lib.rs | 36 ++++++++++++++++++------------------ src/test.rs | 24 +++++++++++++++++++++++- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd27afb..03d171c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "slice-cursor" +name = "slice-utils" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index e15b07a..5a2f770 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "slice-cursor" +name = "slice-utils" version = "0.1.0" edition = "2021" diff --git a/src/lib.rs b/src/lib.rs index 7d33a8e..e1be107 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 { + fn span>(&self, idx: R) -> O; +} + +/// The interface for types that can peek ahead to the next item. +pub trait Peekable { + fn peek_next(&self) -> Option; +} + /// SpanRange encompasses the valid Ops::Range types for use with the Span trait. pub enum SpanRange { Range(std::ops::Range), @@ -74,16 +84,6 @@ impl From for SpanRange { } } -/// An input that can provide a span of a range of the input. -pub trait Span { - fn span>(&self, idx: R) -> O; -} - -/// The interface for types that can peek ahead to the next item. -pub trait Peekable { - fn peek_next(&self) -> Option; -} - /// 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>(&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>(&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), } } } diff --git a/src/test.rs b/src/test.rs index 00357ef..e925c42 100644 --- a/src/test.rs +++ b/src/test.rs @@ -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)); +}