diff options
Diffstat (limited to 'third_party/rust/nom/src/str.rs')
-rw-r--r-- | third_party/rust/nom/src/str.rs | 536 |
1 files changed, 536 insertions, 0 deletions
diff --git a/third_party/rust/nom/src/str.rs b/third_party/rust/nom/src/str.rs new file mode 100644 index 0000000000..1a8b8ba2d4 --- /dev/null +++ b/third_party/rust/nom/src/str.rs @@ -0,0 +1,536 @@ +#[cfg(test)] +mod test { + #[cfg(feature = "alloc")] + use crate::{branch::alt, bytes::complete::tag_no_case, combinator::recognize, multi::many1}; + use crate::{ + bytes::complete::{is_a, is_not, tag, take, take_till, take_until}, + error::{self, ErrorKind}, + Err, IResult, + }; + + #[test] + fn tagtr_succeed() { + const INPUT: &str = "Hello World!"; + const TAG: &str = "Hello"; + fn test(input: &str) -> IResult<&str, &str> { + tag(TAG)(input) + } + + match test(INPUT) { + Ok((extra, output)) => { + assert!(extra == " World!", "Parser `tag` consumed leftover input."); + assert!( + output == TAG, + "Parser `tag` doesn't return the tag it matched on success. \ + Expected `{}`, got `{}`.", + TAG, + output + ); + } + other => panic!( + "Parser `tag` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn tagtr_incomplete() { + use crate::bytes::streaming::tag; + + const INPUT: &str = "Hello"; + const TAG: &str = "Hello World!"; + + let res: IResult<_, _, error::Error<_>> = tag(TAG)(INPUT); + match res { + Err(Err::Incomplete(_)) => (), + other => { + panic!( + "Parser `tag` didn't require more input when it should have. \ + Got `{:?}`.", + other + ); + } + }; + } + + #[test] + fn tagtr_error() { + const INPUT: &str = "Hello World!"; + const TAG: &str = "Random"; // TAG must be closer than INPUT. + + let res: IResult<_, _, error::Error<_>> = tag(TAG)(INPUT); + match res { + Err(Err::Error(_)) => (), + other => { + panic!( + "Parser `tag` didn't fail when it should have. Got `{:?}`.`", + other + ); + } + }; + } + + #[test] + fn take_s_succeed() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + + let res: IResult<_, _, error::Error<_>> = take(9_usize)(INPUT); + match res { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_s` consumed leftover input. Leftover `{}`.", + extra + ); + assert!( + output == CONSUMED, + "Parser `take_s` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_s` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_until_succeed() { + const INPUT: &str = "βèƒôřèÂßÇ∂áƒƭèř"; + const FIND: &str = "ÂßÇ∂"; + const CONSUMED: &str = "βèƒôřè"; + const LEFTOVER: &str = "ÂßÇ∂áƒƭèř"; + + let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); + match res { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_until`\ + consumed leftover input. Leftover `{}`.", + extra + ); + assert!( + output == CONSUMED, + "Parser `take_until`\ + doesn't return the string it consumed on success. Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_until` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_s_incomplete() { + use crate::bytes::streaming::take; + + const INPUT: &str = "βèƒôřèÂßÇá"; + + let res: IResult<_, _, (_, ErrorKind)> = take(13_usize)(INPUT); + match res { + Err(Err::Incomplete(_)) => (), + other => panic!( + "Parser `take` didn't require more input when it should have. \ + Got `{:?}`.", + other + ), + } + } + + use crate::internal::Needed; + + fn is_alphabetic(c: char) -> bool { + (c as u8 >= 0x41 && c as u8 <= 0x5A) || (c as u8 >= 0x61 && c as u8 <= 0x7A) + } + + #[test] + fn take_while() { + use crate::bytes::streaming::take_while; + + fn f(i: &str) -> IResult<&str, &str> { + take_while(is_alphabetic)(i) + } + let a = ""; + let b = "abcd"; + let c = "abcd123"; + let d = "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: &str) -> IResult<&str, &str> { + take_while1(is_alphabetic)(i) + } + let a = ""; + let b = "abcd"; + let c = "abcd123"; + let d = "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((&"123"[..], &b[..]))); + assert_eq!( + f(&d[..]), + Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1))) + ); + } + + #[test] + fn take_till_s_succeed() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + fn till_s(c: char) -> bool { + c == 'á' + } + fn test(input: &str) -> IResult<&str, &str> { + take_till(till_s)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_till` consumed leftover input." + ); + assert!( + output == CONSUMED, + "Parser `take_till` doesn't return the string it consumed on success. \ + Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_till` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_while_succeed_none() { + use crate::bytes::complete::take_while; + + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const CONSUMED: &str = ""; + const LEFTOVER: &str = "βèƒôřèÂßÇáƒƭèř"; + fn while_s(c: char) -> bool { + c == '9' + } + fn test(input: &str) -> IResult<&str, &str> { + take_while(while_s)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_while` consumed leftover input." + ); + assert!( + output == CONSUMED, + "Parser `take_while` doesn't return the string it consumed on success. \ + Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_while` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn is_not_succeed() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const AVOID: &str = "£úçƙ¥á"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + fn test(input: &str) -> IResult<&str, &str> { + is_not(AVOID)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `is_not` consumed leftover input. Leftover `{}`.", + extra + ); + assert!( + output == CONSUMED, + "Parser `is_not` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `is_not` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_while_succeed_some() { + use crate::bytes::complete::take_while; + + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + fn while_s(c: char) -> bool { + c == 'β' + || c == 'è' + || c == 'ƒ' + || c == 'ô' + || c == 'ř' + || c == 'è' + || c == 'Â' + || c == 'ß' + || c == 'Ç' + } + fn test(input: &str) -> IResult<&str, &str> { + take_while(while_s)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_while` consumed leftover input." + ); + assert!( + output == CONSUMED, + "Parser `take_while` doesn't return the string it consumed on success. \ + Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_while` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn is_not_fail() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const AVOID: &str = "βúçƙ¥"; + fn test(input: &str) -> IResult<&str, &str> { + is_not(AVOID)(input) + } + match test(INPUT) { + Err(Err::Error(_)) => (), + other => panic!( + "Parser `is_not` didn't fail when it should have. Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_while1_succeed() { + use crate::bytes::complete::take_while1; + + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + fn while1_s(c: char) -> bool { + c == 'β' + || c == 'è' + || c == 'ƒ' + || c == 'ô' + || c == 'ř' + || c == 'è' + || c == 'Â' + || c == 'ß' + || c == 'Ç' + } + fn test(input: &str) -> IResult<&str, &str> { + take_while1(while1_s)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `take_while1` consumed leftover input." + ); + assert!( + output == CONSUMED, + "Parser `take_while1` doesn't return the string it consumed on success. \ + Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `take_while1` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_until_incomplete() { + use crate::bytes::streaming::take_until; + + const INPUT: &str = "βèƒôřè"; + const FIND: &str = "βèƒôřèÂßÇ"; + + let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); + match res { + Err(Err::Incomplete(_)) => (), + other => panic!( + "Parser `take_until` didn't require more input when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn is_a_succeed() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const MATCH: &str = "βèƒôřèÂßÇ"; + const CONSUMED: &str = "βèƒôřèÂßÇ"; + const LEFTOVER: &str = "áƒƭèř"; + fn test(input: &str) -> IResult<&str, &str> { + is_a(MATCH)(input) + } + match test(INPUT) { + Ok((extra, output)) => { + assert!( + extra == LEFTOVER, + "Parser `is_a` consumed leftover input. Leftover `{}`.", + extra + ); + assert!( + output == CONSUMED, + "Parser `is_a` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", + CONSUMED, + output + ); + } + other => panic!( + "Parser `is_a` didn't succeed when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_while1_fail() { + use crate::bytes::complete::take_while1; + + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + fn while1_s(c: char) -> bool { + c == '9' + } + fn test(input: &str) -> IResult<&str, &str> { + take_while1(while1_s)(input) + } + match test(INPUT) { + Err(Err::Error(_)) => (), + other => panic!( + "Parser `take_while1` didn't fail when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + fn is_a_fail() { + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const MATCH: &str = "Ûñℓúçƙ¥"; + fn test(input: &str) -> IResult<&str, &str> { + is_a(MATCH)(input) + } + match test(INPUT) { + Err(Err::Error(_)) => (), + other => panic!( + "Parser `is_a` didn't fail when it should have. Got `{:?}`.", + other + ), + }; + } + + #[test] + fn take_until_error() { + use crate::bytes::streaming::take_until; + + const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; + const FIND: &str = "Ráñδô₥"; + + let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); + match res { + Err(Err::Incomplete(_)) => (), + other => panic!( + "Parser `take_until` didn't fail when it should have. \ + Got `{:?}`.", + other + ), + }; + } + + #[test] + #[cfg(feature = "alloc")] + fn recognize_is_a() { + let a = "aabbab"; + let b = "ababcd"; + + fn f(i: &str) -> IResult<&str, &str> { + recognize(many1(alt((tag("a"), tag("b")))))(i) + } + + assert_eq!(f(&a[..]), Ok((&a[6..], &a[..]))); + assert_eq!(f(&b[..]), Ok((&b[4..], &b[..4]))); + } + + #[test] + fn utf8_indexing() { + fn dot(i: &str) -> IResult<&str, &str> { + tag(".")(i) + } + + let _ = dot("點"); + } + + #[cfg(feature = "alloc")] + #[test] + fn case_insensitive() { + fn test(i: &str) -> IResult<&str, &str> { + tag_no_case("ABcd")(i) + } + assert_eq!(test("aBCdefgh"), Ok(("efgh", "aBCd"))); + assert_eq!(test("abcdefgh"), Ok(("efgh", "abcd"))); + assert_eq!(test("ABCDefgh"), Ok(("efgh", "ABCD"))); + } +} |