mirror of
https://gitee.com/openharmony/third_party_rust_nom
synced 2024-11-23 07:29:54 +00:00
remove macros from bytes module
This commit is contained in:
parent
f49ba8e9d4
commit
59bf911ad8
@ -1,974 +0,0 @@
|
||||
//! Byte level parsers and combinators
|
||||
//!
|
||||
#[allow(unused_variables)]
|
||||
|
||||
/// `tag!(&[T]: nom::AsBytes) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// declares a byte array as a suite to recognize.
|
||||
///
|
||||
/// Consumes the recognized characters.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(x, tag!("abcd"));
|
||||
/// let r = x(&b"abcdefgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"efgh"[..], &b"abcd"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! tag (
|
||||
($i:expr, $tag: expr) => ({
|
||||
$crate::bytes::streaming::tag($tag)($i)
|
||||
});
|
||||
);
|
||||
|
||||
/// `tag_no_case!(&[T]) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// declares a case insensitive ascii string as a suite to recognize.
|
||||
///
|
||||
/// Consumes the recognized characters.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(test, tag_no_case!("ABcd"));
|
||||
///
|
||||
/// let r = test(&b"aBCdefgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"efgh"[..], &b"aBCd"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! tag_no_case (
|
||||
($i:expr, $tag: expr) => ({
|
||||
$crate::bytes::streaming::tag_no_case($tag)($i)
|
||||
});
|
||||
);
|
||||
|
||||
/// `is_not!(&[T:AsBytes]) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest list of bytes that do not appear in the provided array.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!( not_space, is_not!( " \t\r\n" ) );
|
||||
///
|
||||
/// let r = not_space(&b"abcdefgh\nijkl"[..]);
|
||||
/// assert_eq!(r, Ok((&b"\nijkl"[..], &b"abcdefgh"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! is_not (
|
||||
($input:expr, $arr:expr) => ({
|
||||
$crate::bytes::streaming::is_not($arr)($input)
|
||||
});
|
||||
);
|
||||
|
||||
/// `is_a!(&[T]) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest list of bytes that appear in the provided array.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(abcd, is_a!( "abcd" ));
|
||||
///
|
||||
/// let r1 = abcd(&b"aaaaefgh"[..]);
|
||||
/// assert_eq!(r1, Ok((&b"efgh"[..], &b"aaaa"[..])));
|
||||
///
|
||||
/// let r2 = abcd(&b"dcbaefgh"[..]);
|
||||
/// assert_eq!(r2, Ok((&b"efgh"[..], &b"dcba"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! is_a (
|
||||
($input:expr, $arr:expr) => ({
|
||||
$crate::bytes::streaming::is_a($arr)($input)
|
||||
});
|
||||
);
|
||||
|
||||
/// `escaped!(T -> IResult<T, T>, U, T -> IResult<T, T>) => T -> IResult<T, T> where T: InputIter,
|
||||
/// U: AsChar`
|
||||
/// matches a byte string with escaped characters.
|
||||
///
|
||||
/// * The first argument matches the normal characters (it must not accept the control character)
|
||||
/// * The second argument is the control character (like `\` in most languages)
|
||||
/// * The third argument matches the escaped characters
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! escaped (
|
||||
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
|
||||
{
|
||||
escaped!($i, |i| $submac1!(i, $($args)*), $control_char, |i| $submac2!(i, $($args2)*))
|
||||
}
|
||||
);
|
||||
($i:expr, $normal:expr, $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
|
||||
{
|
||||
escaped!($i, $normal, $control_char, |i| $submac2!(i, $($args2)*))
|
||||
}
|
||||
);
|
||||
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $escapable:expr ) => (
|
||||
{
|
||||
escaped!($i, |i| $submac1!(i, $($args)*), $control_char, $escapable)
|
||||
}
|
||||
);
|
||||
($i:expr, $normal:expr, $control_char: expr, $escapable:expr) => (
|
||||
{
|
||||
$crate::bytes::complete::escapedc($i, $normal, $control_char, $escapable)
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// `escaped_transform!(&[T] -> IResult<&[T], &[T]>, T, &[T] -> IResult<&[T], &[T]>) => &[T] -> IResult<&[T], Vec<T>>`
|
||||
/// matches a byte string with escaped characters.
|
||||
///
|
||||
/// * The first argument matches the normal characters (it must not match the control character)
|
||||
/// * The second argument is the control character (like `\` in most languages)
|
||||
/// * The third argument matches the escaped characters and transforms them
|
||||
///
|
||||
/// As an example, the chain `abc\tdef` could be `abc def` (it also consumes the control character).
|
||||
#[cfg(feature = "alloc")]
|
||||
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! escaped_transform (
|
||||
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
|
||||
{
|
||||
escaped_transform!($i, |i| $submac1!(i, $($args)*), $control_char, |i| $submac2!(i, $($args2)*))
|
||||
}
|
||||
);
|
||||
($i:expr, $normal:expr, $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
|
||||
{
|
||||
escaped_transform!($i, $normal, $control_char, |i| $submac2!(i, $($args2)*))
|
||||
}
|
||||
);
|
||||
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $transform:expr ) => (
|
||||
{
|
||||
escaped_transform!($i, |i| $submac1!(i, $($args)*), $control_char, $transform)
|
||||
}
|
||||
);
|
||||
($i:expr, $normal:expr, $control_char: expr, $transform:expr) => (
|
||||
{
|
||||
$crate::bytes::complete::escaped_transformc($i, $normal, $control_char, $transform)
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_while!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest list of bytes until the provided function fails.
|
||||
///
|
||||
/// The argument is either a function `T -> bool` or a macro returning a `bool`.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # use nom::character::is_alphanumeric;
|
||||
/// # fn main() {
|
||||
/// named!( alpha, take_while!( is_alphanumeric ) );
|
||||
///
|
||||
/// let r = alpha(&b"abcd\nefgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"\nefgh"[..], &b"abcd"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_while (
|
||||
($input:expr, $submac:ident!( $($args:tt)* )) => ({
|
||||
let res: $crate::IResult<_, _, _> = take_while!($input, (|c| $submac!(c, $($args)*)));
|
||||
res
|
||||
});
|
||||
($input:expr, $f:expr) => (
|
||||
$crate::bytes::streaming::take_while($f)($input)
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_while1!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest (non empty) list of bytes until the provided function fails.
|
||||
///
|
||||
/// The argument is either a function `&[T] -> bool` or a macro returning a `bool`.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # use nom::{Err,error::ErrorKind};
|
||||
/// # use nom::character::is_alphanumeric;
|
||||
/// # fn main() {
|
||||
/// named!( alpha, take_while1!( is_alphanumeric ) );
|
||||
///
|
||||
/// let r = alpha(&b"abcd\nefgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"\nefgh"[..], &b"abcd"[..])));
|
||||
/// let r = alpha(&b"\nefgh"[..]);
|
||||
/// assert_eq!(r, Err(Err::Error(error_position!(&b"\nefgh"[..], ErrorKind::TakeWhile1))));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_while1 (
|
||||
($input:expr, $submac:ident!( $($args:tt)* )) => ({
|
||||
let res: $crate::IResult<_, _, _> = take_while1!($input, (|c| $submac!(c, $($args)*)));
|
||||
res
|
||||
});
|
||||
($input:expr, $f:expr) => (
|
||||
$crate::bytes::streaming::take_while1($f)($input)
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_while_m_n!(m: usize, n: usize, T -> bool) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns a list of bytes or characters for which the provided function returns true.
|
||||
/// The returned list's size will be at least m, and at most n.
|
||||
///
|
||||
/// The argument is either a function `T -> bool` or a macro returning a `bool`.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # use nom::character::is_alphanumeric;
|
||||
/// # fn main() {
|
||||
/// named!( alpha, take_while_m_n!(3, 6, is_alphanumeric ) );
|
||||
///
|
||||
/// let r = alpha(&b"abcd\nefgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"\nefgh"[..], &b"abcd"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_while_m_n (
|
||||
($input:expr, $m:expr, $n: expr, $submac:ident!( $($args:tt)* )) => ({
|
||||
let res: $crate::IResult<_, _, _> = take_while_m_n!($input, $m, $n, (|c| $submac!(c, $($args)*)));
|
||||
res
|
||||
});
|
||||
($input:expr, $m:expr, $n:expr, $f:expr) => (
|
||||
$crate::bytes::streaming::take_while_m_n($m, $n, $f)($input)
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_till!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest list of bytes until the provided function succeeds.
|
||||
///
|
||||
/// The argument is either a function `&[T] -> bool` or a macro returning a `bool`.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!( till_colon, take_till!(|ch| ch == b':') );
|
||||
///
|
||||
/// let r = till_colon(&b"abcd:efgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b":efgh"[..], &b"abcd"[..])));
|
||||
/// let r2 = till_colon(&b":abcdefgh"[..]); // empty match is allowed
|
||||
/// assert_eq!(r2, Ok((&b":abcdefgh"[..], &b""[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_till (
|
||||
($input:expr, $submac:ident!( $($args:tt)* )) => ({
|
||||
let res: $crate::IResult<_, _, _> = take_till!($input, (|c| $submac!(c, $($args)*)));
|
||||
res
|
||||
});
|
||||
($input:expr, $f:expr) => (
|
||||
$crate::bytes::streaming::take_till($f)($input)
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_till1!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// returns the longest non empty list of bytes until the provided function succeeds.
|
||||
///
|
||||
/// The argument is either a function `&[T] -> bool` or a macro returning a `bool`.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # use nom::{Err, error::ErrorKind};
|
||||
/// # fn main() {
|
||||
/// named!( till1_colon, take_till1!(|ch| ch == b':') );
|
||||
///
|
||||
/// let r = till1_colon(&b"abcd:efgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b":efgh"[..], &b"abcd"[..])));
|
||||
///
|
||||
/// let r2 = till1_colon(&b":abcdefgh"[..]); // empty match is error
|
||||
/// assert_eq!(r2, Err(Err::Error(error_position!(&b":abcdefgh"[..], ErrorKind::TakeTill1))));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_till1 (
|
||||
($input:expr, $submac:ident!( $($args:tt)* )) => ({
|
||||
let res: $crate::IResult<_, _, _> = take_till1!($input, (|c| $submac!(c, $($args)*)));
|
||||
res
|
||||
});
|
||||
($input:expr, $f:expr) => (
|
||||
$crate::bytes::streaming::take_till1($f)($input)
|
||||
);
|
||||
);
|
||||
|
||||
/// `take!(nb) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// generates a parser consuming the specified number of bytes.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// // Desmond parser
|
||||
/// named!(take5, take!( 5 ) );
|
||||
///
|
||||
/// let a = b"abcdefgh";
|
||||
///
|
||||
/// assert_eq!(take5(&a[..]), Ok((&b"fgh"[..], &b"abcde"[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take (
|
||||
($i:expr, $count:expr) => ({
|
||||
let c = $count as usize;
|
||||
let res: $crate::IResult<_,_,_> = $crate::bytes::streaming::take(c)($i);
|
||||
res
|
||||
});
|
||||
);
|
||||
|
||||
/// `take_str!(nb) => &[T] -> IResult<&[T], &str>`
|
||||
/// same as `take!` but returning a `&str`.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(take5( &[u8] ) -> &str, take_str!( 5 ) );
|
||||
///
|
||||
/// let a = b"abcdefgh";
|
||||
///
|
||||
/// assert_eq!(take5(&a[..]), Ok((&b"fgh"[..], "abcde")));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_str (
|
||||
( $i:expr, $size:expr ) => (
|
||||
{
|
||||
let input: &[u8] = $i;
|
||||
|
||||
map_res!(input, take!($size), $crate::lib::std::str::from_utf8)
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// `take_until!(tag) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// consumes data until it finds the specified tag.
|
||||
///
|
||||
/// The remainder still contains the tag.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(x, take_until!("foo"));
|
||||
/// let r = x(&b"abcd foo efgh"[..]);
|
||||
/// assert_eq!(r, Ok((&b"foo efgh"[..], &b"abcd "[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_until (
|
||||
($i:expr, $substr:expr) => ({
|
||||
let res: $crate::IResult<_,_,_> = $crate::bytes::streaming::take_until($substr)($i);
|
||||
res
|
||||
});
|
||||
);
|
||||
|
||||
/// `take_until1!(tag) => &[T] -> IResult<&[T], &[T]>`
|
||||
/// consumes data (at least one byte) until it finds the specified tag.
|
||||
///
|
||||
/// The remainder still contains the tag.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # fn main() {
|
||||
/// named!(x, take_until1!("foo"));
|
||||
///
|
||||
/// let r = x(&b"abcd foo efgh"[..]);
|
||||
///
|
||||
/// assert_eq!(r, Ok((&b"foo efgh"[..], &b"abcd "[..])));
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! take_until1 (
|
||||
($i:expr, $substr:expr) => (
|
||||
{
|
||||
use $crate::lib::std::result::Result::*;
|
||||
use $crate::lib::std::option::Option::*;
|
||||
use $crate::{Err,Needed,IResult,error::ErrorKind};
|
||||
use $crate::InputLength;
|
||||
use $crate::FindSubstring;
|
||||
use $crate::InputTake;
|
||||
let input = $i;
|
||||
|
||||
let res: IResult<_,_> = match input.find_substring($substr) {
|
||||
None => {
|
||||
Err(Err::Incomplete(Needed::new(1 + $substr.input_len())))
|
||||
},
|
||||
Some(0) => {
|
||||
let e = ErrorKind::TakeUntil;
|
||||
Err(Err::Error(error_position!($i, e)))
|
||||
},
|
||||
Some(index) => {
|
||||
Ok($i.take_split(index))
|
||||
},
|
||||
};
|
||||
res
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::bytes::complete::escaped_transform;
|
||||
use crate::character::is_alphabetic;
|
||||
use crate::character::streaming::{
|
||||
alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
|
||||
multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
|
||||
};
|
||||
use crate::error::ErrorKind;
|
||||
use crate::internal::{Err, IResult, Needed};
|
||||
use crate::{
|
||||
combinator::recognize,
|
||||
sequence::delimited,
|
||||
bytes::streaming::{tag, take}
|
||||
};
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::branch::alt;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::combinator::{map, value};
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::lib::std::string::String;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::lib::std::vec::Vec;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
macro_rules! one_of (
|
||||
($i:expr, $inp: expr) => (
|
||||
{
|
||||
use $crate::Err;
|
||||
use $crate::Slice;
|
||||
use $crate::AsChar;
|
||||
use $crate::FindToken;
|
||||
use $crate::InputIter;
|
||||
|
||||
match ($i).iter_elements().next().map(|c| {
|
||||
$inp.find_token(c)
|
||||
}) {
|
||||
None => Err::<_,_>(Err::Incomplete(Needed::new(1))),
|
||||
Some(false) => Err(Err::Error(error_position!($i, ErrorKind::OneOf))),
|
||||
//the unwrap should be safe here
|
||||
Some(true) => Ok(($i.slice(1..), $i.iter_elements().next().unwrap().as_char()))
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn is_a() {
|
||||
named!(a_or_b, is_a!(&b"ab"[..]));
|
||||
|
||||
let a = &b"abcd"[..];
|
||||
assert_eq!(a_or_b(a), Ok((&b"cd"[..], &b"ab"[..])));
|
||||
|
||||
let b = &b"bcde"[..];
|
||||
assert_eq!(a_or_b(b), Ok((&b"cde"[..], &b"b"[..])));
|
||||
|
||||
let c = &b"cdef"[..];
|
||||
assert_eq!(
|
||||
a_or_b(c),
|
||||
Err(Err::Error(error_position!(c, ErrorKind::IsA)))
|
||||
);
|
||||
|
||||
let d = &b"bacdef"[..];
|
||||
assert_eq!(a_or_b(d), Ok((&b"cdef"[..], &b"ba"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_not() {
|
||||
named!(a_or_b, is_not!(&b"ab"[..]));
|
||||
|
||||
let a = &b"cdab"[..];
|
||||
assert_eq!(a_or_b(a), Ok((&b"ab"[..], &b"cd"[..])));
|
||||
|
||||
let b = &b"cbde"[..];
|
||||
assert_eq!(a_or_b(b), Ok((&b"bde"[..], &b"c"[..])));
|
||||
|
||||
let c = &b"abab"[..];
|
||||
assert_eq!(
|
||||
a_or_b(c),
|
||||
Err(Err::Error(error_position!(c, ErrorKind::IsNot)))
|
||||
);
|
||||
|
||||
let d = &b"cdefba"[..];
|
||||
assert_eq!(a_or_b(d), Ok((&b"ba"[..], &b"cdef"[..])));
|
||||
|
||||
let e = &b"e"[..];
|
||||
assert_eq!(a_or_b(e), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[allow(unused_variables)]
|
||||
#[test]
|
||||
fn escaping() {
|
||||
named!(esc, escaped!(call!(alpha), '\\', one_of!("\"n\\")));
|
||||
assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], &b"abcd"[..])));
|
||||
assert_eq!(esc(&b"ab\\\"cd;"[..]), Ok((&b";"[..], &b"ab\\\"cd"[..])));
|
||||
assert_eq!(esc(&b"\\\"abcd;"[..]), Ok((&b";"[..], &b"\\\"abcd"[..])));
|
||||
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], &b"\\n"[..])));
|
||||
assert_eq!(esc(&b"ab\\\"12"[..]), Ok((&b"12"[..], &b"ab\\\""[..])));
|
||||
assert_eq!(
|
||||
esc(&b"AB\\"[..]),
|
||||
Err(Err::Error(error_position!(
|
||||
&b"AB\\"[..],
|
||||
ErrorKind::Escaped
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\A"[..]),
|
||||
Err(Err::Error(error_node_position!(
|
||||
&b"AB\\A"[..],
|
||||
ErrorKind::Escaped,
|
||||
error_position!(&b"A"[..], ErrorKind::OneOf)
|
||||
)))
|
||||
);
|
||||
|
||||
named!(esc2, escaped!(call!(digit), '\\', one_of!("\"n\\")));
|
||||
assert_eq!(esc2(&b"12\\nnn34"[..]), Ok((&b"nn34"[..], &b"12\\n"[..])));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn escaping_str() {
|
||||
named!(esc<&str, &str>, escaped!(call!(alpha), '\\', one_of!("\"n\\")));
|
||||
assert_eq!(esc("abcd;"), Ok((";", "abcd")));
|
||||
assert_eq!(esc("ab\\\"cd;"), Ok((";", "ab\\\"cd")));
|
||||
assert_eq!(esc("\\\"abcd;"), Ok((";", "\\\"abcd")));
|
||||
assert_eq!(esc("\\n;"), Ok((";", "\\n")));
|
||||
assert_eq!(esc("ab\\\"12"), Ok(("12", "ab\\\"")));
|
||||
assert_eq!(
|
||||
esc("AB\\"),
|
||||
Err(Err::Error(error_position!("AB\\", ErrorKind::Escaped)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc("AB\\A"),
|
||||
Err(Err::Error(error_node_position!(
|
||||
"AB\\A",
|
||||
ErrorKind::Escaped,
|
||||
error_position!("A", ErrorKind::OneOf)
|
||||
)))
|
||||
);
|
||||
|
||||
named!(esc2<&str, &str>, escaped!(call!(digit), '\\', one_of!("\"n\\")));
|
||||
assert_eq!(esc2("12\\nnn34"), Ok(("nn34", "12\\n")));
|
||||
|
||||
named!(esc3<&str, &str>, escaped!(call!(alpha), '\u{241b}', one_of!("\"n")));
|
||||
assert_eq!(esc3("ab␛ncd;"), Ok((";", "ab␛ncd")));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
fn to_s(i: Vec<u8>) -> String {
|
||||
String::from_utf8_lossy(&i).into_owned()
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn escape_transform() {
|
||||
fn esc(i: &[u8]) -> IResult<&[u8], String> {
|
||||
map(
|
||||
escaped_transform(alpha, '\\',
|
||||
alt((
|
||||
value(&b"\\"[..], tag("\\")),
|
||||
value(&b"\""[..], tag("\"")),
|
||||
value(&b"\n"[..], tag("n")),
|
||||
))),
|
||||
to_s)(i)
|
||||
}
|
||||
|
||||
assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], String::from("abcd"))));
|
||||
assert_eq!(
|
||||
esc(&b"ab\\\"cd;"[..]),
|
||||
Ok((&b";"[..], String::from("ab\"cd")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"\\\"abcd;"[..]),
|
||||
Ok((&b";"[..], String::from("\"abcd")))
|
||||
);
|
||||
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], String::from("\n"))));
|
||||
assert_eq!(
|
||||
esc(&b"ab\\\"12"[..]),
|
||||
Ok((&b"12"[..], String::from("ab\"")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\"[..]),
|
||||
Err(Err::Error(error_position!(
|
||||
&b"\\"[..],
|
||||
ErrorKind::EscapedTransform
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\A"[..]),
|
||||
Err(Err::Error(error_node_position!(
|
||||
&b"AB\\A"[..],
|
||||
ErrorKind::EscapedTransform,
|
||||
error_position!(&b"A"[..], ErrorKind::Tag)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &[u8]) -> IResult<&[u8], String> {
|
||||
map(
|
||||
escaped_transform(alpha, '&',
|
||||
alt((
|
||||
value("è".as_bytes(), tag("egrave;")),
|
||||
value("à".as_bytes(), tag("agrave;"))
|
||||
))),
|
||||
to_s)(i)
|
||||
}
|
||||
assert_eq!(
|
||||
esc2(&b"abèDEF;"[..]),
|
||||
Ok((&b";"[..], String::from("abèDEF")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc2(&b"abèDàEF;"[..]),
|
||||
Ok((&b";"[..], String::from("abèDàEF")))
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn escape_transform_str() {
|
||||
fn esc(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(alpha, '\\',
|
||||
alt((
|
||||
value("\\", tag("\\")),
|
||||
value("\"", tag("\"")),
|
||||
value("\n", tag("n")),
|
||||
)))(i)
|
||||
}
|
||||
|
||||
assert_eq!(esc("abcd;"), Ok((";", String::from("abcd"))));
|
||||
assert_eq!(esc("ab\\\"cd;"), Ok((";", String::from("ab\"cd"))));
|
||||
assert_eq!(esc("\\\"abcd;"), Ok((";", String::from("\"abcd"))));
|
||||
assert_eq!(esc("\\n;"), Ok((";", String::from("\n"))));
|
||||
assert_eq!(esc("ab\\\"12"), Ok(("12", String::from("ab\""))));
|
||||
assert_eq!(
|
||||
esc("AB\\"),
|
||||
Err(Err::Error(error_position!(
|
||||
"\\",
|
||||
ErrorKind::EscapedTransform
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc("AB\\A"),
|
||||
Err(Err::Error(error_node_position!(
|
||||
"AB\\A",
|
||||
ErrorKind::EscapedTransform,
|
||||
error_position!("A", ErrorKind::Tag)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(alpha, '&',
|
||||
alt((
|
||||
value("è", tag("egrave;")),
|
||||
value("à", tag("agrave;"))
|
||||
)))(i)
|
||||
}
|
||||
assert_eq!(esc2("abèDEF;"), Ok((";", String::from("abèDEF"))));
|
||||
assert_eq!(
|
||||
esc2("abèDàEF;"),
|
||||
Ok((";", String::from("abèDàEF")))
|
||||
);
|
||||
|
||||
fn esc3(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(alpha, '␛',
|
||||
alt((
|
||||
value("\0", tag("0")),
|
||||
value("\n", tag("n"))
|
||||
)))(i)
|
||||
}
|
||||
assert_eq!(esc3("a␛0bc␛n"), Ok(("", String::from("a\0bc\n"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_str_test() {
|
||||
let a = b"omnomnom";
|
||||
|
||||
let res: IResult<_, _, (&[u8], ErrorKind)> = take_str!(&a[..], 5u32);
|
||||
assert_eq!(res, Ok((&b"nom"[..], "omnom")));
|
||||
|
||||
let res: IResult<_, _, (&[u8], ErrorKind)> = take_str!(&a[..], 9u32);
|
||||
assert_eq!(res, Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_until_incomplete() {
|
||||
named!(y, take_until!("end"));
|
||||
assert_eq!(y(&b"nd"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(y(&b"123"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(y(&b"123en"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_until_incomplete_s() {
|
||||
named!(ys<&str, &str>, take_until!("end"));
|
||||
assert_eq!(ys("123en"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recognize_test() {
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(delimited(tag("<!--"), take(5usize), tag("-->")))(i)
|
||||
}
|
||||
|
||||
let r = x(&b"<!-- abc --> aaa"[..]);
|
||||
assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
|
||||
|
||||
let semicolon = &b";"[..];
|
||||
|
||||
named!(ya, recognize!(alpha));
|
||||
let ra = ya(&b"abc;"[..]);
|
||||
assert_eq!(ra, Ok((semicolon, &b"abc"[..])));
|
||||
|
||||
named!(yd, recognize!(digit));
|
||||
let rd = yd(&b"123;"[..]);
|
||||
assert_eq!(rd, Ok((semicolon, &b"123"[..])));
|
||||
|
||||
named!(yhd, recognize!(hex_digit));
|
||||
let rhd = yhd(&b"123abcDEF;"[..]);
|
||||
assert_eq!(rhd, Ok((semicolon, &b"123abcDEF"[..])));
|
||||
|
||||
named!(yod, recognize!(oct_digit));
|
||||
let rod = yod(&b"1234567;"[..]);
|
||||
assert_eq!(rod, Ok((semicolon, &b"1234567"[..])));
|
||||
|
||||
named!(yan, recognize!(alphanumeric));
|
||||
let ran = yan(&b"123abc;"[..]);
|
||||
assert_eq!(ran, Ok((semicolon, &b"123abc"[..])));
|
||||
|
||||
named!(ys, recognize!(space));
|
||||
let rs = ys(&b" \t;"[..]);
|
||||
assert_eq!(rs, Ok((semicolon, &b" \t"[..])));
|
||||
|
||||
named!(yms, recognize!(multispace));
|
||||
let rms = yms(&b" \t\r\n;"[..]);
|
||||
assert_eq!(rms, Ok((semicolon, &b" \t\r\n"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while() {
|
||||
named!(f, take_while!(is_alphabetic));
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"abcd123";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&c[..]), Ok((&d[..], &b[..])));
|
||||
assert_eq!(f(&d[..]), Ok((&d[..], &a[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while1() {
|
||||
named!(f, take_while1!(is_alphabetic));
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"abcd123";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&c[..]), Ok((&b"123"[..], &b[..])));
|
||||
assert_eq!(
|
||||
f(&d[..]),
|
||||
Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n() {
|
||||
named!(x, take_while_m_n!(2, 4, is_alphabetic));
|
||||
let a = b"";
|
||||
let b = b"a";
|
||||
let c = b"abc";
|
||||
let d = b"abc123";
|
||||
let e = b"abcde";
|
||||
let f = b"123";
|
||||
|
||||
assert_eq!(x(&a[..]), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(x(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(&c[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(&d[..]), Ok((&b"123"[..], &c[..])));
|
||||
assert_eq!(x(&e[..]), Ok((&b"e"[..], &b"abcd"[..])));
|
||||
assert_eq!(
|
||||
x(&f[..]),
|
||||
Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till() {
|
||||
named!(f, take_till!(is_alphabetic));
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"123abcd";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Ok((&b"abcd"[..], &b""[..])));
|
||||
assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
|
||||
assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till1() {
|
||||
named!(f, take_till1!(is_alphabetic));
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"123abcd";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(
|
||||
f(&b[..]),
|
||||
Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1)))
|
||||
);
|
||||
assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
|
||||
assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_utf8() {
|
||||
named!(f<&str,&str>, take_while!(|c:char| { c != '點' }));
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd點"), Ok(("點", "abcd")));
|
||||
assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
|
||||
|
||||
named!(g<&str,&str>, take_while!(|c:char| { c == '點' }));
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till_utf8() {
|
||||
named!(f<&str,&str>, take_till!(|c:char| { c == '點' }));
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd點"), Ok(("點", "abcd")));
|
||||
assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
|
||||
|
||||
named!(g<&str,&str>, take_till!(|c:char| { c != '點' }));
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_utf8() {
|
||||
named!(f<&str,&str>, take!(3));
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("ab"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("點"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("ab點cd"), Ok(("cd", "ab點")));
|
||||
assert_eq!(f("a點bcd"), Ok(("cd", "a點b")));
|
||||
assert_eq!(f("a點b"), Ok(("", "a點b")));
|
||||
|
||||
named!(g<&str,&str>, take_while!(|c:char| { c == '點' }));
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n_utf8() {
|
||||
named!(parser<&str, &str>, take_while_m_n!(1, 1, |c| c == 'A' || c == '😃'));
|
||||
assert_eq!(parser("A!"), Ok(("!", "A")));
|
||||
assert_eq!(parser("😃!"), Ok(("!", "😃")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n_utf8_full_match() {
|
||||
named!(parser<&str, &str>, take_while_m_n!(1, 1, |c: char| c.is_alphabetic()));
|
||||
assert_eq!(parser("øn"), Ok(("n", "ø")));
|
||||
}
|
||||
|
||||
#[cfg(nightly)]
|
||||
use test::Bencher;
|
||||
|
||||
#[cfg(nightly)]
|
||||
#[bench]
|
||||
fn take_while_bench(b: &mut Bencher) {
|
||||
named!(f, take_while!(is_alphabetic));
|
||||
b.iter(|| f(&b"abcdefghijklABCDEejfrfrjgro12aa"[..]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "std")]
|
||||
fn recognize_take_while() {
|
||||
use crate::character::is_alphanumeric;
|
||||
named!(x, take_while!(is_alphanumeric));
|
||||
named!(y, recognize!(x));
|
||||
assert_eq!(x(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
|
||||
println!("X: {:?}", x(&b"ab"[..]));
|
||||
assert_eq!(y(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length_bytes() {
|
||||
use crate::{
|
||||
number::streaming::le_u8,
|
||||
bytes::streaming::tag,
|
||||
multi::length_data
|
||||
};
|
||||
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
length_data(le_u8)(i)
|
||||
}
|
||||
assert_eq!(x(b"\x02..>>"), Ok((&b">>"[..], &b".."[..])));
|
||||
assert_eq!(x(b"\x02.."), Ok((&[][..], &b".."[..])));
|
||||
assert_eq!(x(b"\x02."), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(b"\x02"), Err(Err::Incomplete(Needed::new(2))));
|
||||
|
||||
fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (i, _) = tag("magic")(i)?;
|
||||
length_data(le_u8)(i)
|
||||
}
|
||||
assert_eq!(y(b"magic\x02..>>"), Ok((&b">>"[..], &b".."[..])));
|
||||
assert_eq!(y(b"magic\x02.."), Ok((&[][..], &b".."[..])));
|
||||
assert_eq!(y(b"magic\x02."), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(y(b"magic\x02"), Err(Err::Incomplete(Needed::new(2))));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn case_insensitive() {
|
||||
named!(test, tag_no_case!("ABcd"));
|
||||
assert_eq!(test(&b"aBCdefgh"[..]), Ok((&b"efgh"[..], &b"aBCd"[..])));
|
||||
assert_eq!(test(&b"abcdefgh"[..]), Ok((&b"efgh"[..], &b"abcd"[..])));
|
||||
assert_eq!(test(&b"ABCDefgh"[..]), Ok((&b"efgh"[..], &b"ABCD"[..])));
|
||||
assert_eq!(test(&b"ab"[..]), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(
|
||||
test(&b"Hello"[..]),
|
||||
Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag)))
|
||||
);
|
||||
assert_eq!(
|
||||
test(&b"Hel"[..]),
|
||||
Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag)))
|
||||
);
|
||||
|
||||
named!(test2<&str, &str>, tag_no_case!("ABcd"));
|
||||
assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
|
||||
assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
|
||||
assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
|
||||
assert_eq!(test2("ab"), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(
|
||||
test2("Hello"),
|
||||
Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag)))
|
||||
);
|
||||
assert_eq!(
|
||||
test2("Hel"),
|
||||
Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tag_fixed_size_array() {
|
||||
named!(test, tag!([0x42]));
|
||||
named!(test2, tag!(&[0x42]));
|
||||
let input = [0x42, 0x00];
|
||||
assert_eq!(test(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
|
||||
assert_eq!(test2(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
//! Parsers recognizing bytes streams
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub mod complete;
|
||||
pub mod streaming;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
640
src/bytes/tests.rs
Normal file
640
src/bytes/tests.rs
Normal file
@ -0,0 +1,640 @@
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::branch::alt;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::bytes::complete::tag;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::bytes::complete::{escaped, escaped_transform};
|
||||
use crate::character::is_alphabetic;
|
||||
use crate::character::streaming::{
|
||||
alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
|
||||
multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
|
||||
};
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::combinator::{map, value};
|
||||
use crate::error::ErrorKind;
|
||||
use crate::internal::{Err, IResult, Needed};
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::lib::std::string::String;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::lib::std::vec::Vec;
|
||||
|
||||
#[test]
|
||||
fn is_a() {
|
||||
use crate::bytes::streaming::is_a;
|
||||
|
||||
fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
is_a("ab")(i)
|
||||
}
|
||||
|
||||
let a = &b"abcd"[..];
|
||||
assert_eq!(a_or_b(a), Ok((&b"cd"[..], &b"ab"[..])));
|
||||
|
||||
let b = &b"bcde"[..];
|
||||
assert_eq!(a_or_b(b), Ok((&b"cde"[..], &b"b"[..])));
|
||||
|
||||
let c = &b"cdef"[..];
|
||||
assert_eq!(
|
||||
a_or_b(c),
|
||||
Err(Err::Error(error_position!(c, ErrorKind::IsA)))
|
||||
);
|
||||
|
||||
let d = &b"bacdef"[..];
|
||||
assert_eq!(a_or_b(d), Ok((&b"cdef"[..], &b"ba"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_not() {
|
||||
use crate::bytes::streaming::is_not;
|
||||
|
||||
fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
is_not("ab")(i)
|
||||
}
|
||||
|
||||
let a = &b"cdab"[..];
|
||||
assert_eq!(a_or_b(a), Ok((&b"ab"[..], &b"cd"[..])));
|
||||
|
||||
let b = &b"cbde"[..];
|
||||
assert_eq!(a_or_b(b), Ok((&b"bde"[..], &b"c"[..])));
|
||||
|
||||
let c = &b"abab"[..];
|
||||
assert_eq!(
|
||||
a_or_b(c),
|
||||
Err(Err::Error(error_position!(c, ErrorKind::IsNot)))
|
||||
);
|
||||
|
||||
let d = &b"cdefba"[..];
|
||||
assert_eq!(a_or_b(d), Ok((&b"ba"[..], &b"cdef"[..])));
|
||||
|
||||
let e = &b"e"[..];
|
||||
assert_eq!(a_or_b(e), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[allow(unused_variables)]
|
||||
#[test]
|
||||
fn escaping() {
|
||||
use crate::character::streaming::one_of;
|
||||
|
||||
fn esc(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
escaped(alpha, '\\', one_of("\"n\\"))(i)
|
||||
}
|
||||
assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], &b"abcd"[..])));
|
||||
assert_eq!(esc(&b"ab\\\"cd;"[..]), Ok((&b";"[..], &b"ab\\\"cd"[..])));
|
||||
assert_eq!(esc(&b"\\\"abcd;"[..]), Ok((&b";"[..], &b"\\\"abcd"[..])));
|
||||
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], &b"\\n"[..])));
|
||||
assert_eq!(esc(&b"ab\\\"12"[..]), Ok((&b"12"[..], &b"ab\\\""[..])));
|
||||
assert_eq!(
|
||||
esc(&b"AB\\"[..]),
|
||||
Err(Err::Error(error_position!(
|
||||
&b"AB\\"[..],
|
||||
ErrorKind::Escaped
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\A"[..]),
|
||||
Err(Err::Error(error_node_position!(
|
||||
&b"AB\\A"[..],
|
||||
ErrorKind::Escaped,
|
||||
error_position!(&b"A"[..], ErrorKind::OneOf)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
escaped(digit, '\\', one_of("\"n\\"))(i)
|
||||
}
|
||||
assert_eq!(esc2(&b"12\\nnn34"[..]), Ok((&b"nn34"[..], &b"12\\n"[..])));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn escaping_str() {
|
||||
use crate::character::streaming::one_of;
|
||||
|
||||
fn esc(i: &str) -> IResult<&str, &str> {
|
||||
escaped(alpha, '\\', one_of("\"n\\"))(i)
|
||||
}
|
||||
assert_eq!(esc("abcd;"), Ok((";", "abcd")));
|
||||
assert_eq!(esc("ab\\\"cd;"), Ok((";", "ab\\\"cd")));
|
||||
assert_eq!(esc("\\\"abcd;"), Ok((";", "\\\"abcd")));
|
||||
assert_eq!(esc("\\n;"), Ok((";", "\\n")));
|
||||
assert_eq!(esc("ab\\\"12"), Ok(("12", "ab\\\"")));
|
||||
assert_eq!(
|
||||
esc("AB\\"),
|
||||
Err(Err::Error(error_position!("AB\\", ErrorKind::Escaped)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc("AB\\A"),
|
||||
Err(Err::Error(error_node_position!(
|
||||
"AB\\A",
|
||||
ErrorKind::Escaped,
|
||||
error_position!("A", ErrorKind::OneOf)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &str) -> IResult<&str, &str> {
|
||||
escaped(digit, '\\', one_of("\"n\\"))(i)
|
||||
}
|
||||
assert_eq!(esc2("12\\nnn34"), Ok(("nn34", "12\\n")));
|
||||
|
||||
fn esc3(i: &str) -> IResult<&str, &str> {
|
||||
escaped(alpha, '\u{241b}', one_of("\"n"))(i)
|
||||
}
|
||||
assert_eq!(esc3("ab␛ncd;"), Ok((";", "ab␛ncd")));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
fn to_s(i: Vec<u8>) -> String {
|
||||
String::from_utf8_lossy(&i).into_owned()
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn escape_transform() {
|
||||
fn esc(i: &[u8]) -> IResult<&[u8], String> {
|
||||
map(
|
||||
escaped_transform(
|
||||
alpha,
|
||||
'\\',
|
||||
alt((
|
||||
value(&b"\\"[..], tag("\\")),
|
||||
value(&b"\""[..], tag("\"")),
|
||||
value(&b"\n"[..], tag("n")),
|
||||
)),
|
||||
),
|
||||
to_s,
|
||||
)(i)
|
||||
}
|
||||
|
||||
assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], String::from("abcd"))));
|
||||
assert_eq!(
|
||||
esc(&b"ab\\\"cd;"[..]),
|
||||
Ok((&b";"[..], String::from("ab\"cd")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"\\\"abcd;"[..]),
|
||||
Ok((&b";"[..], String::from("\"abcd")))
|
||||
);
|
||||
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], String::from("\n"))));
|
||||
assert_eq!(
|
||||
esc(&b"ab\\\"12"[..]),
|
||||
Ok((&b"12"[..], String::from("ab\"")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\"[..]),
|
||||
Err(Err::Error(error_position!(
|
||||
&b"\\"[..],
|
||||
ErrorKind::EscapedTransform
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc(&b"AB\\A"[..]),
|
||||
Err(Err::Error(error_node_position!(
|
||||
&b"AB\\A"[..],
|
||||
ErrorKind::EscapedTransform,
|
||||
error_position!(&b"A"[..], ErrorKind::Tag)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &[u8]) -> IResult<&[u8], String> {
|
||||
map(
|
||||
escaped_transform(
|
||||
alpha,
|
||||
'&',
|
||||
alt((
|
||||
value("è".as_bytes(), tag("egrave;")),
|
||||
value("à".as_bytes(), tag("agrave;")),
|
||||
)),
|
||||
),
|
||||
to_s,
|
||||
)(i)
|
||||
}
|
||||
assert_eq!(
|
||||
esc2(&b"abèDEF;"[..]),
|
||||
Ok((&b";"[..], String::from("abèDEF")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc2(&b"abèDàEF;"[..]),
|
||||
Ok((&b";"[..], String::from("abèDàEF")))
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn escape_transform_str() {
|
||||
fn esc(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(
|
||||
alpha,
|
||||
'\\',
|
||||
alt((
|
||||
value("\\", tag("\\")),
|
||||
value("\"", tag("\"")),
|
||||
value("\n", tag("n")),
|
||||
)),
|
||||
)(i)
|
||||
}
|
||||
|
||||
assert_eq!(esc("abcd;"), Ok((";", String::from("abcd"))));
|
||||
assert_eq!(esc("ab\\\"cd;"), Ok((";", String::from("ab\"cd"))));
|
||||
assert_eq!(esc("\\\"abcd;"), Ok((";", String::from("\"abcd"))));
|
||||
assert_eq!(esc("\\n;"), Ok((";", String::from("\n"))));
|
||||
assert_eq!(esc("ab\\\"12"), Ok(("12", String::from("ab\""))));
|
||||
assert_eq!(
|
||||
esc("AB\\"),
|
||||
Err(Err::Error(error_position!(
|
||||
"\\",
|
||||
ErrorKind::EscapedTransform
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
esc("AB\\A"),
|
||||
Err(Err::Error(error_node_position!(
|
||||
"AB\\A",
|
||||
ErrorKind::EscapedTransform,
|
||||
error_position!("A", ErrorKind::Tag)
|
||||
)))
|
||||
);
|
||||
|
||||
fn esc2(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(
|
||||
alpha,
|
||||
'&',
|
||||
alt((value("è", tag("egrave;")), value("à", tag("agrave;")))),
|
||||
)(i)
|
||||
}
|
||||
assert_eq!(esc2("abèDEF;"), Ok((";", String::from("abèDEF"))));
|
||||
assert_eq!(
|
||||
esc2("abèDàEF;"),
|
||||
Ok((";", String::from("abèDàEF")))
|
||||
);
|
||||
|
||||
fn esc3(i: &str) -> IResult<&str, String> {
|
||||
escaped_transform(
|
||||
alpha,
|
||||
'␛',
|
||||
alt((value("\0", tag("0")), value("\n", tag("n")))),
|
||||
)(i)
|
||||
}
|
||||
assert_eq!(esc3("a␛0bc␛n"), Ok(("", String::from("a\0bc\n"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_until_incomplete() {
|
||||
use crate::bytes::streaming::take_until;
|
||||
fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_until("end")(i)
|
||||
}
|
||||
assert_eq!(y(&b"nd"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(y(&b"123"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(y(&b"123en"[..]), Err(Err::Incomplete(Needed::Unknown)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_until_incomplete_s() {
|
||||
use crate::bytes::streaming::take_until;
|
||||
fn ys(i: &str) -> IResult<&str, &str> {
|
||||
take_until("end")(i)
|
||||
}
|
||||
assert_eq!(ys("123en"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recognize() {
|
||||
use crate::bytes::streaming::{tag, take};
|
||||
use crate::combinator::recognize;
|
||||
use crate::sequence::delimited;
|
||||
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(delimited(tag("<!--"), take(5_usize), tag("-->")))(i)
|
||||
}
|
||||
let r = x(&b"<!-- abc --> aaa"[..]);
|
||||
assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
|
||||
|
||||
let semicolon = &b";"[..];
|
||||
|
||||
fn ya(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(alpha)(i)
|
||||
}
|
||||
let ra = ya(&b"abc;"[..]);
|
||||
assert_eq!(ra, Ok((semicolon, &b"abc"[..])));
|
||||
|
||||
fn yd(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(digit)(i)
|
||||
}
|
||||
let rd = yd(&b"123;"[..]);
|
||||
assert_eq!(rd, Ok((semicolon, &b"123"[..])));
|
||||
|
||||
fn yhd(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(hex_digit)(i)
|
||||
}
|
||||
let rhd = yhd(&b"123abcDEF;"[..]);
|
||||
assert_eq!(rhd, Ok((semicolon, &b"123abcDEF"[..])));
|
||||
|
||||
fn yod(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(oct_digit)(i)
|
||||
}
|
||||
let rod = yod(&b"1234567;"[..]);
|
||||
assert_eq!(rod, Ok((semicolon, &b"1234567"[..])));
|
||||
|
||||
fn yan(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(alphanumeric)(i)
|
||||
}
|
||||
let ran = yan(&b"123abc;"[..]);
|
||||
assert_eq!(ran, Ok((semicolon, &b"123abc"[..])));
|
||||
|
||||
fn ys(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(space)(i)
|
||||
}
|
||||
let rs = ys(&b" \t;"[..]);
|
||||
assert_eq!(rs, Ok((semicolon, &b" \t"[..])));
|
||||
|
||||
fn yms(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(multispace)(i)
|
||||
}
|
||||
let rms = yms(&b" \t\r\n;"[..]);
|
||||
assert_eq!(rms, Ok((semicolon, &b" \t\r\n"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while() {
|
||||
use crate::bytes::streaming::take_while;
|
||||
|
||||
fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_while(is_alphabetic)(i)
|
||||
}
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"abcd123";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&c[..]), Ok((&d[..], &b[..])));
|
||||
assert_eq!(f(&d[..]), Ok((&d[..], &a[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while1() {
|
||||
use crate::bytes::streaming::take_while1;
|
||||
|
||||
fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_while1(is_alphabetic)(i)
|
||||
}
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"abcd123";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&c[..]), Ok((&b"123"[..], &b[..])));
|
||||
assert_eq!(
|
||||
f(&d[..]),
|
||||
Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n() {
|
||||
use crate::bytes::streaming::take_while_m_n;
|
||||
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_while_m_n(2, 4, is_alphabetic)(i)
|
||||
}
|
||||
let a = b"";
|
||||
let b = b"a";
|
||||
let c = b"abc";
|
||||
let d = b"abc123";
|
||||
let e = b"abcde";
|
||||
let f = b"123";
|
||||
|
||||
assert_eq!(x(&a[..]), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(x(&b[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(&c[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(&d[..]), Ok((&b"123"[..], &c[..])));
|
||||
assert_eq!(x(&e[..]), Ok((&b"e"[..], &b"abcd"[..])));
|
||||
assert_eq!(
|
||||
x(&f[..]),
|
||||
Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till() {
|
||||
use crate::bytes::streaming::take_till;
|
||||
|
||||
fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_till(is_alphabetic)(i)
|
||||
}
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"123abcd";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f(&b[..]), Ok((&b"abcd"[..], &b""[..])));
|
||||
assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
|
||||
assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till1() {
|
||||
use crate::bytes::streaming::take_till1;
|
||||
|
||||
fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_till1(is_alphabetic)(i)
|
||||
}
|
||||
let a = b"";
|
||||
let b = b"abcd";
|
||||
let c = b"123abcd";
|
||||
let d = b"123";
|
||||
|
||||
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(
|
||||
f(&b[..]),
|
||||
Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1)))
|
||||
);
|
||||
assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
|
||||
assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_utf8() {
|
||||
use crate::bytes::streaming::take_while;
|
||||
|
||||
fn f(i: &str) -> IResult<&str, &str> {
|
||||
take_while(|c| c != '點')(i)
|
||||
}
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd點"), Ok(("點", "abcd")));
|
||||
assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
|
||||
|
||||
fn g(i: &str) -> IResult<&str, &str> {
|
||||
take_while(|c| c == '點')(i)
|
||||
}
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_till_utf8() {
|
||||
use crate::bytes::streaming::take_till;
|
||||
|
||||
fn f(i: &str) -> IResult<&str, &str> {
|
||||
take_till(|c| c == '點')(i)
|
||||
}
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(f("abcd點"), Ok(("點", "abcd")));
|
||||
assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
|
||||
|
||||
fn g(i: &str) -> IResult<&str, &str> {
|
||||
take_till(|c| c != '點')(i)
|
||||
}
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_utf8() {
|
||||
use crate::bytes::streaming::{take, take_while};
|
||||
|
||||
fn f(i: &str) -> IResult<&str, &str> {
|
||||
take(3_usize)(i)
|
||||
}
|
||||
|
||||
assert_eq!(f(""), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("ab"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("點"), Err(Err::Incomplete(Needed::Unknown)));
|
||||
assert_eq!(f("ab點cd"), Ok(("cd", "ab點")));
|
||||
assert_eq!(f("a點bcd"), Ok(("cd", "a點b")));
|
||||
assert_eq!(f("a點b"), Ok(("", "a點b")));
|
||||
|
||||
fn g(i: &str) -> IResult<&str, &str> {
|
||||
take_while(|c| c == '點')(i)
|
||||
}
|
||||
|
||||
assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(g("點abcd"), Ok(("abcd", "點")));
|
||||
assert_eq!(g("點點點a"), Ok(("a", "點點點")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n_utf8() {
|
||||
use crate::bytes::streaming::take_while_m_n;
|
||||
|
||||
fn parser(i: &str) -> IResult<&str, &str> {
|
||||
take_while_m_n(1, 1, |c| c == 'A' || c == '😃')(i)
|
||||
}
|
||||
assert_eq!(parser("A!"), Ok(("!", "A")));
|
||||
assert_eq!(parser("😃!"), Ok(("!", "😃")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_while_m_n_utf8_full_match() {
|
||||
use crate::bytes::streaming::take_while_m_n;
|
||||
|
||||
fn parser(i: &str) -> IResult<&str, &str> {
|
||||
take_while_m_n(1, 1, |c: char| c.is_alphabetic())(i)
|
||||
}
|
||||
assert_eq!(parser("øn"), Ok(("n", "ø")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "std")]
|
||||
fn recognize_take_while() {
|
||||
use crate::bytes::streaming::take_while;
|
||||
use crate::character::is_alphanumeric;
|
||||
use crate::combinator::recognize;
|
||||
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_while(is_alphanumeric)(i)
|
||||
}
|
||||
fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
recognize(x)(i)
|
||||
}
|
||||
assert_eq!(x(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
|
||||
println!("X: {:?}", x(&b"ab"[..]));
|
||||
assert_eq!(y(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length_bytes() {
|
||||
use crate::{bytes::streaming::tag, multi::length_data, number::streaming::le_u8};
|
||||
|
||||
fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
length_data(le_u8)(i)
|
||||
}
|
||||
assert_eq!(x(b"\x02..>>"), Ok((&b">>"[..], &b".."[..])));
|
||||
assert_eq!(x(b"\x02.."), Ok((&[][..], &b".."[..])));
|
||||
assert_eq!(x(b"\x02."), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(x(b"\x02"), Err(Err::Incomplete(Needed::new(2))));
|
||||
|
||||
fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (i, _) = tag("magic")(i)?;
|
||||
length_data(le_u8)(i)
|
||||
}
|
||||
assert_eq!(y(b"magic\x02..>>"), Ok((&b">>"[..], &b".."[..])));
|
||||
assert_eq!(y(b"magic\x02.."), Ok((&[][..], &b".."[..])));
|
||||
assert_eq!(y(b"magic\x02."), Err(Err::Incomplete(Needed::new(1))));
|
||||
assert_eq!(y(b"magic\x02"), Err(Err::Incomplete(Needed::new(2))));
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn case_insensitive() {
|
||||
use crate::bytes::streaming::tag_no_case;
|
||||
|
||||
fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
tag_no_case("ABcd")(i)
|
||||
}
|
||||
assert_eq!(test(&b"aBCdefgh"[..]), Ok((&b"efgh"[..], &b"aBCd"[..])));
|
||||
assert_eq!(test(&b"abcdefgh"[..]), Ok((&b"efgh"[..], &b"abcd"[..])));
|
||||
assert_eq!(test(&b"ABCDefgh"[..]), Ok((&b"efgh"[..], &b"ABCD"[..])));
|
||||
assert_eq!(test(&b"ab"[..]), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(
|
||||
test(&b"Hello"[..]),
|
||||
Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag)))
|
||||
);
|
||||
assert_eq!(
|
||||
test(&b"Hel"[..]),
|
||||
Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag)))
|
||||
);
|
||||
|
||||
fn test2(i: &str) -> IResult<&str, &str> {
|
||||
tag_no_case("ABcd")(i)
|
||||
}
|
||||
assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
|
||||
assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
|
||||
assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
|
||||
assert_eq!(test2("ab"), Err(Err::Incomplete(Needed::new(2))));
|
||||
assert_eq!(
|
||||
test2("Hello"),
|
||||
Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag)))
|
||||
);
|
||||
assert_eq!(
|
||||
test2("Hel"),
|
||||
Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tag_fixed_size_array() {
|
||||
use crate::bytes::streaming::tag;
|
||||
|
||||
fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
tag([0x42])(i)
|
||||
}
|
||||
fn test2(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
tag(&[0x42])(i)
|
||||
}
|
||||
let input = [0x42, 0x00];
|
||||
assert_eq!(test(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
|
||||
assert_eq!(test2(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
|
||||
}
|
Loading…
Reference in New Issue
Block a user