diff --git a/examples/ndjson/main.rs b/examples/ndjson/main.rs index d81b6900..11f25c4a 100644 --- a/examples/ndjson/main.rs +++ b/examples/ndjson/main.rs @@ -43,7 +43,7 @@ fn main() -> Result<(), lexopt::Error> { println!("{:?}", value); println!(); // Tell the buffer how much we read - let consumed = input.offset_to(&remainder); + let consumed = remainder.offset_from(&input); buffer.consume(consumed); } Err(ErrMode::Backtrack(e)) | Err(ErrMode::Cut(e)) => { diff --git a/src/ascii/mod.rs b/src/ascii/mod.rs index 23cc74ed..c9ffe077 100644 --- a/src/ascii/mod.rs +++ b/src/ascii/mod.rs @@ -124,7 +124,7 @@ where c == '\r' || c == '\n' }) { None if PARTIAL && input.is_partial() => Err(ErrMode::Incomplete(Needed::Unknown)), - None => Ok(input.next_slice(input.eof_offset())), + None => Ok(input.finish()), Some(offset) => { let (new_input, res) = input.next_slice(offset); let bytes = new_input.as_bstr(); @@ -944,7 +944,7 @@ where if ::is_partial_supported() && input.is_partial() { Err(ErrMode::Incomplete(Needed::new(1))) } else { - Ok((input.next_slice(input.eof_offset()).0, value)) + Ok((input.finish().0, value)) } }) .parse_next(input) @@ -1109,7 +1109,7 @@ where if ::is_partial_supported() && input.is_partial() { Err(ErrMode::Incomplete(Needed::new(1))) } else { - Ok((input.next_slice(input.eof_offset()).0, value)) + Ok((input.finish().0, value)) } }) .parse_next(input) @@ -1480,7 +1480,7 @@ where if i2.eof_offset() == 0 { return Err(ErrMode::Incomplete(Needed::Unknown)); } else if i2.eof_offset() == current_len { - let offset = input.offset_to(&i2); + let offset = i2.offset_from(&input); return Ok(input.next_slice(offset)); } else { i = i2; @@ -1496,7 +1496,7 @@ where i = i2; } } else { - let offset = input.offset_to(&i); + let offset = i.offset_from(&input); return Ok(input.next_slice(offset)); } } @@ -1535,7 +1535,7 @@ where if i2.eof_offset() == 0 { return Ok(input.next_slice(input.eof_offset())); } else if i2.eof_offset() == current_len { - let offset = input.offset_to(&i2); + let offset = i2.offset_from(&input); return Ok(input.next_slice(offset)); } else { i = i2; @@ -1546,12 +1546,12 @@ where let next = control_char.len_utf8(); let (i2, _) = escapable.parse_next(i.next_slice(next).0)?; if i2.eof_offset() == 0 { - return Ok(input.next_slice(input.eof_offset())); + return Ok(input.finish()); } else { i = i2; } } else { - let offset = input.offset_to(&i); + let offset = i.offset_from(&input); return Ok(input.next_slice(offset)); } } @@ -1561,7 +1561,7 @@ where } } - Ok(input.next_slice(input.eof_offset())) + Ok(input.finish()) } /// Matches a byte string with escaped characters. @@ -1680,7 +1680,7 @@ where } else if i2.eof_offset() == current_len { return Ok((remainder, res)); } else { - offset = input.offset_to(&i2); + offset = i2.offset_from(&input); } } Err(ErrMode::Backtrack(_)) => { @@ -1691,7 +1691,7 @@ where if i2.eof_offset() == 0 { return Err(ErrMode::Incomplete(Needed::Unknown)); } else { - offset = input.offset_to(&i2); + offset = i2.offset_from(&input); } } else { return Ok((remainder, res)); @@ -1735,7 +1735,7 @@ where } else if i2.eof_offset() == current_len { return Ok((remainder, res)); } else { - offset = input.offset_to(&i2); + offset = i2.offset_from(&input); } } Err(ErrMode::Backtrack(_)) => { @@ -1744,9 +1744,9 @@ where let (i2, o) = transform.parse_next(i.next_slice(next).0)?; res.accumulate(o); if i2.eof_offset() == 0 { - return Ok((i.next_slice(i.eof_offset()).0, res)); + return Ok((i.finish().0, res)); } else { - offset = input.offset_to(&i2); + offset = i2.offset_from(&input); } } else { return Ok((remainder, res)); diff --git a/src/ascii/tests.rs b/src/ascii/tests.rs index 59da69fa..09ddab3e 100644 --- a/src/ascii/tests.rs +++ b/src/ascii/tests.rs @@ -155,43 +155,43 @@ mod complete { match alpha1::<_, Error<_>>(a) { Ok((i, _)) => { - assert_eq!(a.offset_to(i) + i.len(), a.len()); + assert_eq!(i.offset_from(a) + i.len(), a.len()); } _ => panic!("wrong return type in offset test for alpha"), } match digit1::<_, Error<_>>(b) { Ok((i, _)) => { - assert_eq!(b.offset_to(i) + i.len(), b.len()); + assert_eq!(i.offset_from(b) + i.len(), b.len()); } _ => panic!("wrong return type in offset test for digit"), } match alphanumeric1::<_, Error<_>>(c) { Ok((i, _)) => { - assert_eq!(c.offset_to(i) + i.len(), c.len()); + assert_eq!(i.offset_from(c) + i.len(), c.len()); } _ => panic!("wrong return type in offset test for alphanumeric"), } match space1::<_, Error<_>>(d) { Ok((i, _)) => { - assert_eq!(d.offset_to(i) + i.len(), d.len()); + assert_eq!(i.offset_from(d) + i.len(), d.len()); } _ => panic!("wrong return type in offset test for space"), } match multispace1::<_, Error<_>>(e) { Ok((i, _)) => { - assert_eq!(e.offset_to(i) + i.len(), e.len()); + assert_eq!(i.offset_from(e) + i.len(), e.len()); } _ => panic!("wrong return type in offset test for multispace"), } match hex_digit1::<_, Error<_>>(f) { Ok((i, _)) => { - assert_eq!(f.offset_to(i) + i.len(), f.len()); + assert_eq!(i.offset_from(f) + i.len(), f.len()); } _ => panic!("wrong return type in offset test for hex_digit"), } match oct_digit1::<_, Error<_>>(f) { Ok((i, _)) => { - assert_eq!(f.offset_to(i) + i.len(), f.len()); + assert_eq!(i.offset_from(f) + i.len(), f.len()); } _ => panic!("wrong return type in offset test for oct_digit"), } @@ -1099,49 +1099,49 @@ mod partial { match alpha1::<_, Error<_>>(Partial::new(a)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(a.offset_to(i) + i.len(), a.len()); + assert_eq!(i.offset_from(a) + i.len(), a.len()); } _ => panic!("wrong return type in offset test for alpha"), } match digit1::<_, Error<_>>(Partial::new(b)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(b.offset_to(i) + i.len(), b.len()); + assert_eq!(i.offset_from(b) + i.len(), b.len()); } _ => panic!("wrong return type in offset test for digit"), } match alphanumeric1::<_, Error<_>>(Partial::new(c)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(c.offset_to(i) + i.len(), c.len()); + assert_eq!(i.offset_from(c) + i.len(), c.len()); } _ => panic!("wrong return type in offset test for alphanumeric"), } match space1::<_, Error<_>>(Partial::new(d)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(d.offset_to(i) + i.len(), d.len()); + assert_eq!(i.offset_from(d) + i.len(), d.len()); } _ => panic!("wrong return type in offset test for space"), } match multispace1::<_, Error<_>>(Partial::new(e)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(e.offset_to(i) + i.len(), e.len()); + assert_eq!(i.offset_from(e) + i.len(), e.len()); } _ => panic!("wrong return type in offset test for multispace"), } match hex_digit1::<_, Error<_>>(Partial::new(f)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(f.offset_to(i) + i.len(), f.len()); + assert_eq!(i.offset_from(f) + i.len(), f.len()); } _ => panic!("wrong return type in offset test for hex_digit"), } match oct_digit1::<_, Error<_>>(Partial::new(f)) { Ok((i, _)) => { let i = i.into_inner(); - assert_eq!(f.offset_to(i) + i.len(), f.len()); + assert_eq!(i.offset_from(f) + i.len(), f.len()); } _ => panic!("wrong return type in offset test for oct_digit"), } diff --git a/src/combinator/core.rs b/src/combinator/core.rs index 5ccf980b..c7cc62d0 100644 --- a/src/combinator/core.rs +++ b/src/combinator/core.rs @@ -19,10 +19,7 @@ pub fn rest>(input: I) -> IResult::Slice, E where I: Stream, { - trace("rest", move |input: I| { - Ok(input.next_slice(input.eof_offset())) - }) - .parse_next(input) + trace("rest", move |input: I| Ok(input.finish())).parse_next(input) } /// Return the length of the remaining input. diff --git a/src/combinator/parser.rs b/src/combinator/parser.rs index ca03b293..19c9084a 100644 --- a/src/combinator/parser.rs +++ b/src/combinator/parser.rs @@ -540,7 +540,7 @@ where let i = input.clone(); match (self.parser).parse_next(i) { Ok((i, _)) => { - let offset = input.offset_to(&i); + let offset = i.offset_from(&input); Ok(input.next_slice(offset)) } Err(e) => Err(e), @@ -585,7 +585,7 @@ where let i = input.clone(); match (self.parser).parse_next(i) { Ok((remaining, result)) => { - let offset = input.offset_to(&remaining); + let offset = remaining.offset_from(&input); let (remaining, recognized) = input.next_slice(offset); Ok((remaining, (result, recognized))) } diff --git a/src/combinator/tests.rs b/src/combinator/tests.rs index cdb78776..9a172160 100644 --- a/src/combinator/tests.rs +++ b/src/combinator/tests.rs @@ -9,6 +9,7 @@ use crate::error::Error; use crate::error::ErrorKind; use crate::error::Needed; use crate::error::ParseError; +use crate::stream::Stream; use crate::token::take; use crate::IResult; use crate::Parser; @@ -560,7 +561,7 @@ fn alt_test() { } fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - Ok((&b""[..], input)) + Ok(input.finish()) } #[allow(unused_variables)] diff --git a/src/error.rs b/src/error.rs index 6e00ebba..a9a54f5e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -505,9 +505,10 @@ pub fn convert_error>( use crate::stream::Offset; let mut result = crate::lib::std::string::String::new(); + let input = &*input; for (i, (substring, kind)) in e.errors.iter().enumerate() { - let offset = input.offset_to(substring); + let offset = substring.offset_from(input); if input.is_empty() { match kind { @@ -541,7 +542,7 @@ pub fn convert_error>( .trim_end(); // The (1-indexed) column number is the offset of our substring into that line - let column_number = line.offset_to(substring) + 1; + let column_number = substring.offset_from(line) + 1; match kind { VerboseErrorKind::Context(s) => write!( diff --git a/src/stream/mod.rs b/src/stream/mod.rs index 8d82d62c..86ac201b 100644 --- a/src/stream/mod.rs +++ b/src/stream/mod.rs @@ -103,7 +103,7 @@ where } fn location(&self) -> usize { - self.initial.offset_to(&self.input) + self.input.offset_from(&self.initial) } } @@ -449,6 +449,12 @@ pub trait Stream: Offset + Clone + crate::lib::std::fmt::Debug { /// sequence boundaries. /// fn next_slice(&self, offset: usize) -> (Self, Self::Slice); + + /// Advance to the end of the stream + #[inline(always)] + fn finish(&self) -> (Self, Self::Slice) { + self.next_slice(self.eof_offset()) + } } impl<'i, T> Stream for &'i [T] @@ -1120,23 +1126,23 @@ where /// Useful functions to calculate the offset between slices and show a hexdump of a slice pub trait Offset { - /// Offset between the first byte of self and the first byte of the argument - fn offset_to(&self, second: &Self) -> usize; + /// Offset between the first byte of `start` and the first byte of `self` + fn offset_from(&self, start: &Self) -> usize; } impl<'a, T> Offset for &'a [T] { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - (*self).offset_to(*second) + fn offset_from(&self, start: &Self) -> usize { + (*self).offset_from(*start) } } /// Convenience implementation to accept `&[T]` instead of `&&[T]` as above impl Offset for [T] { #[inline] - fn offset_to(&self, second: &Self) -> usize { - let fst = self.as_ptr(); - let snd = second.as_ptr(); + fn offset_from(&self, start: &Self) -> usize { + let fst = start.as_ptr(); + let snd = self.as_ptr(); debug_assert!( fst <= snd, @@ -1148,44 +1154,44 @@ impl Offset for [T] { impl<'a> Offset for &'a str { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } /// Convenience implementation to accept `&str` instead of `&&str` as above impl Offset for str { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } impl Offset for Bytes { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } impl<'a> Offset for &'a Bytes { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } impl Offset for BStr { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } impl<'a> Offset for &'a BStr { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.as_bytes().offset_to(second.as_bytes()) + fn offset_from(&self, start: &Self) -> usize { + self.as_bytes().offset_from(start.as_bytes()) } } @@ -1194,8 +1200,8 @@ where I: Offset, { #[inline(always)] - fn offset_to(&self, other: &Self) -> usize { - self.0.offset_to(&other.0) * 8 + other.1 - self.1 + fn offset_from(&self, start: &Self) -> usize { + self.0.offset_from(&start.0) * 8 + self.1 - start.1 } } @@ -1204,8 +1210,8 @@ where I: Offset, { #[inline(always)] - fn offset_to(&self, other: &Self) -> usize { - self.input.offset_to(&other.input) + fn offset_from(&self, other: &Self) -> usize { + self.input.offset_from(&other.input) } } @@ -1214,8 +1220,8 @@ where I: Offset, { #[inline(always)] - fn offset_to(&self, other: &Self) -> usize { - self.input.offset_to(&other.input) + fn offset_from(&self, start: &Self) -> usize { + self.input.offset_from(&start.input) } } @@ -1224,8 +1230,8 @@ where I: Offset, { #[inline(always)] - fn offset_to(&self, second: &Self) -> usize { - self.input.offset_to(&second.input) + fn offset_from(&self, start: &Self) -> usize { + self.input.offset_from(&start.input) } } diff --git a/src/stream/tests.rs b/src/stream/tests.rs index de61df09..446419f4 100644 --- a/src/stream/tests.rs +++ b/src/stream/tests.rs @@ -10,9 +10,9 @@ fn test_offset_u8() { let b = &a[2..]; let c = &a[..4]; let d = &a[3..5]; - assert_eq!(a.offset_to(b), 2); - assert_eq!(a.offset_to(c), 0); - assert_eq!(a.offset_to(d), 3); + assert_eq!(b.offset_from(a), 2); + assert_eq!(c.offset_from(a), 0); + assert_eq!(d.offset_from(a), 3); } #[test] @@ -21,9 +21,9 @@ fn test_offset_str() { let b = &a[7..]; let c = &a[..5]; let d = &a[5..9]; - assert_eq!(a.offset_to(b), 7); - assert_eq!(a.offset_to(c), 0); - assert_eq!(a.offset_to(d), 5); + assert_eq!(b.offset_from(a), 7); + assert_eq!(c.offset_from(a), 0); + assert_eq!(d.offset_from(a), 5); } #[test] @@ -56,7 +56,7 @@ fn test_bit_stream_empty() { fn test_bit_offset_empty() { let i = (&b""[..], 0); - let actual = i.offset_to(&i); + let actual = i.offset_from(&i); assert_eq!(actual, 0); } @@ -81,7 +81,7 @@ fn bit_stream_inner(byte_len: usize, start: usize) { let mut curr_i = i; let mut curr_offset = 0; while let Some((next_i, _token)) = curr_i.next_token() { - let to_offset = i.offset_to(&curr_i); + let to_offset = curr_i.offset_from(&i); assert_eq!(curr_offset, to_offset); let (slice_i, _) = i.next_slice(curr_offset); diff --git a/src/token/mod.rs b/src/token/mod.rs index 2a92c010..d0ab85af 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -587,7 +587,7 @@ where } if PARTIAL && input.is_partial() { if final_count == n { - Ok(input.next_slice(input.eof_offset())) + Ok(input.finish()) } else { let needed = if m > input.eof_offset() { m - input.eof_offset() @@ -598,7 +598,7 @@ where } } else { if m <= final_count { - Ok(input.next_slice(input.eof_offset())) + Ok(input.finish()) } else { Err(ErrMode::from_error_kind(input, ErrorKind::Slice)) } diff --git a/src/trace/mod.rs b/src/trace/mod.rs index e5eaf945..5cffc169 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -61,14 +61,7 @@ pub fn trace( let res = parser.parse_next(i); - let consumed = res.as_ref().ok().map(|(i, _)| { - if i.eof_offset() == 0 { - // Sometimes, an unrelated empty string is returned which can break `offset_to` - original.eof_offset() - } else { - original.offset_to(i) - } - }); + let consumed = res.as_ref().ok().map(|(i, _)| i.offset_from(&original)); let severity = internals::Severity::with_result(&res); internals::end(*depth, &name, call_count, consumed, severity); call_count += 1;