Skip to content

Commit

Permalink
issues-1223 Add InputSkip trait
Browse files Browse the repository at this point in the history
  • Loading branch information
ikrivosheev committed Oct 27, 2022
1 parent 3645656 commit 371705e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/bytes/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::lib::std::ops::RangeFrom;
use crate::lib::std::result::Result::*;
use crate::traits::{
Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
InputTakeAtPosition, Slice, ToUsize,
InputTakeAtPosition, Slice, ToUsize, InputSkip,
};

/// Recognizes a pattern
Expand Down Expand Up @@ -414,6 +414,37 @@ where
}
}

/// Skip a slice of N input elements (Input[N..]).
///
/// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument.
/// # Example
/// ```rust
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::skip;
///
/// fn skip6(s: &str) -> IResult<&str, ()> {
/// skip(6usize)(s)
/// }
///
/// assert_eq!(skip6("1234567"), Ok(("7", ())));
/// assert_eq!(skip6("things"), Ok(("", ())));
/// assert_eq!(skip6("short"), Err(Err::Error(Error::new("short", ErrorKind::Eof))));
/// assert_eq!(skip6(""), Err(Err::Error(Error::new("", ErrorKind::Eof))));
/// ```
pub fn skip<C, Input, Error: ParseError<Input>>(
count: C,
) -> impl Fn(Input) -> IResult<Input, (), Error>
where
Input: InputIter + InputSkip,
C: ToUsize,
{
let c = count.to_usize();
move |i: Input| match i.slice_index(c) {
Err(_needed) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Eof))),
Ok(index) => Ok((i.skip(index), ())),
}
}

/// Returns the input slice up to the first occurrence of the pattern.
///
/// It doesn't consume the pattern. It will return `Err(Err::Error((_, ErrorKind::TakeUntil)))`
Expand Down
20 changes: 20 additions & 0 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,12 @@ pub trait InputTake: Sized {
fn take_split(&self, count: usize) -> (Self, Self);
}

/// Abstracts skipping operation
pub trait InputSkip: Sized {
/// Skip a slice of `count` bytes. panics if count > length
fn skip(&self, count: usize) -> Self;
}

impl<'a> InputIter for &'a [u8] {
type Item = u8;
type Iter = Enumerate<Self::IterElem>;
Expand Down Expand Up @@ -427,6 +433,20 @@ impl<'a> InputTake for &'a str {
}
}

impl<'a> InputSkip for &'a [u8] {
#[inline]
fn skip(&self, count: usize) -> Self {
&self[count..]
}
}

impl<'a> InputSkip for &'a str {
#[inline]
fn skip(&self, count: usize) -> Self {
&self[count..]
}
}

/// Dummy trait used for default implementations (currently only used for `InputTakeAtPosition` and `Compare`).
///
/// When implementing a custom input type, it is possible to use directly the
Expand Down

0 comments on commit 371705e

Please sign in to comment.