xref: /third_party/rust/crates/nom/tests/issues.rs (revision 6855e09e)
16855e09eSopenharmony_ci//#![feature(trace_macros)]
26855e09eSopenharmony_ci#![allow(dead_code)]
36855e09eSopenharmony_ci#![cfg_attr(feature = "cargo-clippy", allow(redundant_closure))]
46855e09eSopenharmony_ci
56855e09eSopenharmony_ciuse nom::{error::ErrorKind, Err, IResult, Needed};
66855e09eSopenharmony_ci
76855e09eSopenharmony_ci#[allow(dead_code)]
86855e09eSopenharmony_cistruct Range {
96855e09eSopenharmony_ci  start: char,
106855e09eSopenharmony_ci  end: char,
116855e09eSopenharmony_ci}
126855e09eSopenharmony_ci
136855e09eSopenharmony_cipub fn take_char(input: &[u8]) -> IResult<&[u8], char> {
146855e09eSopenharmony_ci  if !input.is_empty() {
156855e09eSopenharmony_ci    Ok((&input[1..], input[0] as char))
166855e09eSopenharmony_ci  } else {
176855e09eSopenharmony_ci    Err(Err::Incomplete(Needed::new(1)))
186855e09eSopenharmony_ci  }
196855e09eSopenharmony_ci}
206855e09eSopenharmony_ci
216855e09eSopenharmony_ci#[cfg(feature = "std")]
226855e09eSopenharmony_cimod parse_int {
236855e09eSopenharmony_ci  use nom::HexDisplay;
246855e09eSopenharmony_ci  use nom::{
256855e09eSopenharmony_ci    character::streaming::{digit1 as digit, space1 as space},
266855e09eSopenharmony_ci    combinator::{complete, map, opt},
276855e09eSopenharmony_ci    multi::many0,
286855e09eSopenharmony_ci    IResult,
296855e09eSopenharmony_ci  };
306855e09eSopenharmony_ci  use std::str;
316855e09eSopenharmony_ci
326855e09eSopenharmony_ci  fn parse_ints(input: &[u8]) -> IResult<&[u8], Vec<i32>> {
336855e09eSopenharmony_ci    many0(spaces_or_int)(input)
346855e09eSopenharmony_ci  }
356855e09eSopenharmony_ci
366855e09eSopenharmony_ci  fn spaces_or_int(input: &[u8]) -> IResult<&[u8], i32> {
376855e09eSopenharmony_ci    println!("{}", input.to_hex(8));
386855e09eSopenharmony_ci    let (i, _) = opt(complete(space))(input)?;
396855e09eSopenharmony_ci    let (i, res) = map(complete(digit), |x| {
406855e09eSopenharmony_ci      println!("x: {:?}", x);
416855e09eSopenharmony_ci      let result = str::from_utf8(x).unwrap();
426855e09eSopenharmony_ci      println!("Result: {}", result);
436855e09eSopenharmony_ci      println!("int is empty?: {}", x.is_empty());
446855e09eSopenharmony_ci      match result.parse() {
456855e09eSopenharmony_ci        Ok(i) => i,
466855e09eSopenharmony_ci        Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
476855e09eSopenharmony_ci      }
486855e09eSopenharmony_ci    })(i)?;
496855e09eSopenharmony_ci
506855e09eSopenharmony_ci    Ok((i, res))
516855e09eSopenharmony_ci  }
526855e09eSopenharmony_ci
536855e09eSopenharmony_ci  #[test]
546855e09eSopenharmony_ci  fn issue_142() {
556855e09eSopenharmony_ci    let subject = parse_ints(&b"12 34 5689a"[..]);
566855e09eSopenharmony_ci    let expected = Ok((&b"a"[..], vec![12, 34, 5689]));
576855e09eSopenharmony_ci    assert_eq!(subject, expected);
586855e09eSopenharmony_ci
596855e09eSopenharmony_ci    let subject = parse_ints(&b"12 34 5689 "[..]);
606855e09eSopenharmony_ci    let expected = Ok((&b" "[..], vec![12, 34, 5689]));
616855e09eSopenharmony_ci    assert_eq!(subject, expected)
626855e09eSopenharmony_ci  }
636855e09eSopenharmony_ci}
646855e09eSopenharmony_ci
656855e09eSopenharmony_ci#[test]
666855e09eSopenharmony_cifn usize_length_bytes_issue() {
676855e09eSopenharmony_ci  use nom::multi::length_data;
686855e09eSopenharmony_ci  use nom::number::streaming::be_u16;
696855e09eSopenharmony_ci  let _: IResult<&[u8], &[u8], (&[u8], ErrorKind)> = length_data(be_u16)(b"012346");
706855e09eSopenharmony_ci}
716855e09eSopenharmony_ci
726855e09eSopenharmony_ci#[test]
736855e09eSopenharmony_cifn take_till_issue() {
746855e09eSopenharmony_ci  use nom::bytes::streaming::take_till;
756855e09eSopenharmony_ci
766855e09eSopenharmony_ci  fn nothing(i: &[u8]) -> IResult<&[u8], &[u8]> {
776855e09eSopenharmony_ci    take_till(|_| true)(i)
786855e09eSopenharmony_ci  }
796855e09eSopenharmony_ci
806855e09eSopenharmony_ci  assert_eq!(nothing(b""), Err(Err::Incomplete(Needed::new(1))));
816855e09eSopenharmony_ci  assert_eq!(nothing(b"abc"), Ok((&b"abc"[..], &b""[..])));
826855e09eSopenharmony_ci}
836855e09eSopenharmony_ci
846855e09eSopenharmony_ci#[test]
856855e09eSopenharmony_cifn issue_655() {
866855e09eSopenharmony_ci  use nom::character::streaming::{line_ending, not_line_ending};
876855e09eSopenharmony_ci  fn twolines(i: &str) -> IResult<&str, (&str, &str)> {
886855e09eSopenharmony_ci    let (i, l1) = not_line_ending(i)?;
896855e09eSopenharmony_ci    let (i, _) = line_ending(i)?;
906855e09eSopenharmony_ci    let (i, l2) = not_line_ending(i)?;
916855e09eSopenharmony_ci    let (i, _) = line_ending(i)?;
926855e09eSopenharmony_ci
936855e09eSopenharmony_ci    Ok((i, (l1, l2)))
946855e09eSopenharmony_ci  }
956855e09eSopenharmony_ci
966855e09eSopenharmony_ci  assert_eq!(twolines("foo\nbar\n"), Ok(("", ("foo", "bar"))));
976855e09eSopenharmony_ci  assert_eq!(twolines("féo\nbar\n"), Ok(("", ("féo", "bar"))));
986855e09eSopenharmony_ci  assert_eq!(twolines("foé\nbar\n"), Ok(("", ("foé", "bar"))));
996855e09eSopenharmony_ci  assert_eq!(twolines("foé\r\nbar\n"), Ok(("", ("foé", "bar"))));
1006855e09eSopenharmony_ci}
1016855e09eSopenharmony_ci
1026855e09eSopenharmony_ci#[cfg(feature = "alloc")]
1036855e09eSopenharmony_cifn issue_717(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
1046855e09eSopenharmony_ci  use nom::bytes::complete::{is_not, tag};
1056855e09eSopenharmony_ci  use nom::multi::separated_list0;
1066855e09eSopenharmony_ci
1076855e09eSopenharmony_ci  separated_list0(tag([0x0]), is_not([0x0u8]))(i)
1086855e09eSopenharmony_ci}
1096855e09eSopenharmony_ci
1106855e09eSopenharmony_cimod issue_647 {
1116855e09eSopenharmony_ci  use nom::bytes::streaming::tag;
1126855e09eSopenharmony_ci  use nom::combinator::complete;
1136855e09eSopenharmony_ci  use nom::multi::separated_list0;
1146855e09eSopenharmony_ci  use nom::{error::Error, number::streaming::be_f64, Err, IResult};
1156855e09eSopenharmony_ci  pub type Input<'a> = &'a [u8];
1166855e09eSopenharmony_ci
1176855e09eSopenharmony_ci  #[derive(PartialEq, Debug, Clone)]
1186855e09eSopenharmony_ci  struct Data {
1196855e09eSopenharmony_ci    c: f64,
1206855e09eSopenharmony_ci    v: Vec<f64>,
1216855e09eSopenharmony_ci  }
1226855e09eSopenharmony_ci
1236855e09eSopenharmony_ci  fn list<'a, 'b>(
1246855e09eSopenharmony_ci    input: Input<'a>,
1256855e09eSopenharmony_ci    _cs: &'b f64,
1266855e09eSopenharmony_ci  ) -> Result<(Input<'a>, Vec<f64>), Err<Error<&'a [u8]>>> {
1276855e09eSopenharmony_ci    separated_list0(complete(tag(",")), complete(be_f64))(input)
1286855e09eSopenharmony_ci  }
1296855e09eSopenharmony_ci
1306855e09eSopenharmony_ci  fn data(input: Input<'_>) -> IResult<Input<'_>, Data> {
1316855e09eSopenharmony_ci    let (i, c) = be_f64(input)?;
1326855e09eSopenharmony_ci    let (i, _) = tag("\n")(i)?;
1336855e09eSopenharmony_ci    let (i, v) = list(i, &c)?;
1346855e09eSopenharmony_ci    Ok((i, Data { c, v }))
1356855e09eSopenharmony_ci  }
1366855e09eSopenharmony_ci}
1376855e09eSopenharmony_ci
1386855e09eSopenharmony_ci#[test]
1396855e09eSopenharmony_cifn issue_848_overflow_incomplete_bits_to_bytes() {
1406855e09eSopenharmony_ci  fn take(i: &[u8]) -> IResult<&[u8], &[u8]> {
1416855e09eSopenharmony_ci    use nom::bytes::streaming::take;
1426855e09eSopenharmony_ci    take(0x2000000000000000_usize)(i)
1436855e09eSopenharmony_ci  }
1446855e09eSopenharmony_ci  fn parser(i: &[u8]) -> IResult<&[u8], &[u8]> {
1456855e09eSopenharmony_ci    use nom::bits::{bits, bytes};
1466855e09eSopenharmony_ci
1476855e09eSopenharmony_ci    bits(bytes(take))(i)
1486855e09eSopenharmony_ci  }
1496855e09eSopenharmony_ci  assert_eq!(
1506855e09eSopenharmony_ci    parser(&b""[..]),
1516855e09eSopenharmony_ci    Err(Err::Failure(nom::error_position!(
1526855e09eSopenharmony_ci      &b""[..],
1536855e09eSopenharmony_ci      ErrorKind::TooLarge
1546855e09eSopenharmony_ci    )))
1556855e09eSopenharmony_ci  );
1566855e09eSopenharmony_ci}
1576855e09eSopenharmony_ci
1586855e09eSopenharmony_ci#[test]
1596855e09eSopenharmony_cifn issue_942() {
1606855e09eSopenharmony_ci  use nom::error::{ContextError, ParseError};
1616855e09eSopenharmony_ci  pub fn parser<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
1626855e09eSopenharmony_ci    i: &'a str,
1636855e09eSopenharmony_ci  ) -> IResult<&'a str, usize, E> {
1646855e09eSopenharmony_ci    use nom::{character::complete::char, error::context, multi::many0_count};
1656855e09eSopenharmony_ci    many0_count(context("char_a", char('a')))(i)
1666855e09eSopenharmony_ci  }
1676855e09eSopenharmony_ci  assert_eq!(parser::<()>("aaa"), Ok(("", 3)));
1686855e09eSopenharmony_ci}
1696855e09eSopenharmony_ci
1706855e09eSopenharmony_ci#[test]
1716855e09eSopenharmony_cifn issue_many_m_n_with_zeros() {
1726855e09eSopenharmony_ci  use nom::character::complete::char;
1736855e09eSopenharmony_ci  use nom::multi::many_m_n;
1746855e09eSopenharmony_ci  let mut parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
1756855e09eSopenharmony_ci  assert_eq!(parser("aaa"), Ok(("aaa", vec![])));
1766855e09eSopenharmony_ci}
1776855e09eSopenharmony_ci
1786855e09eSopenharmony_ci#[test]
1796855e09eSopenharmony_cifn issue_1027_convert_error_panic_nonempty() {
1806855e09eSopenharmony_ci  use nom::character::complete::char;
1816855e09eSopenharmony_ci  use nom::error::{convert_error, VerboseError};
1826855e09eSopenharmony_ci  use nom::sequence::pair;
1836855e09eSopenharmony_ci
1846855e09eSopenharmony_ci  let input = "a";
1856855e09eSopenharmony_ci
1866855e09eSopenharmony_ci  let result: IResult<_, _, VerboseError<&str>> = pair(char('a'), char('b'))(input);
1876855e09eSopenharmony_ci  let err = match result.unwrap_err() {
1886855e09eSopenharmony_ci    Err::Error(e) => e,
1896855e09eSopenharmony_ci    _ => unreachable!(),
1906855e09eSopenharmony_ci  };
1916855e09eSopenharmony_ci
1926855e09eSopenharmony_ci  let msg = convert_error(input, err);
1936855e09eSopenharmony_ci  assert_eq!(
1946855e09eSopenharmony_ci    msg,
1956855e09eSopenharmony_ci    "0: at line 1:\na\n ^\nexpected \'b\', got end of input\n\n"
1966855e09eSopenharmony_ci  );
1976855e09eSopenharmony_ci}
1986855e09eSopenharmony_ci
1996855e09eSopenharmony_ci#[test]
2006855e09eSopenharmony_cifn issue_1231_bits_expect_fn_closure() {
2016855e09eSopenharmony_ci  use nom::bits::{bits, complete::take};
2026855e09eSopenharmony_ci  use nom::error::Error;
2036855e09eSopenharmony_ci  use nom::sequence::tuple;
2046855e09eSopenharmony_ci  pub fn example(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
2056855e09eSopenharmony_ci    bits::<_, _, Error<_>, _, _>(tuple((take(1usize), take(1usize))))(input)
2066855e09eSopenharmony_ci  }
2076855e09eSopenharmony_ci  assert_eq!(example(&[0xff]), Ok((&b""[..], (1, 1))));
2086855e09eSopenharmony_ci}
2096855e09eSopenharmony_ci
2106855e09eSopenharmony_ci#[test]
2116855e09eSopenharmony_cifn issue_1282_findtoken_char() {
2126855e09eSopenharmony_ci  use nom::character::complete::one_of;
2136855e09eSopenharmony_ci  use nom::error::Error;
2146855e09eSopenharmony_ci  let parser = one_of::<_, _, Error<_>>(&['a', 'b', 'c'][..]);
2156855e09eSopenharmony_ci  assert_eq!(parser("aaa"), Ok(("aa", 'a')));
2166855e09eSopenharmony_ci}
2176855e09eSopenharmony_ci
2186855e09eSopenharmony_ci#[test]
2196855e09eSopenharmony_cifn issue_1459_clamp_capacity() {
2206855e09eSopenharmony_ci  use nom::character::complete::char;
2216855e09eSopenharmony_ci
2226855e09eSopenharmony_ci  // shouldn't panic
2236855e09eSopenharmony_ci  use nom::multi::many_m_n;
2246855e09eSopenharmony_ci  let mut parser = many_m_n::<_, _, (), _>(usize::MAX, usize::MAX, char('a'));
2256855e09eSopenharmony_ci  assert_eq!(parser("a"), Err(nom::Err::Error(())));
2266855e09eSopenharmony_ci
2276855e09eSopenharmony_ci  // shouldn't panic
2286855e09eSopenharmony_ci  use nom::multi::count;
2296855e09eSopenharmony_ci  let mut parser = count::<_, _, (), _>(char('a'), usize::MAX);
2306855e09eSopenharmony_ci  assert_eq!(parser("a"), Err(nom::Err::Error(())));
2316855e09eSopenharmony_ci}
2326855e09eSopenharmony_ci
2336855e09eSopenharmony_ci#[test]
2346855e09eSopenharmony_cifn issue_1617_count_parser_returning_zero_size() {
2356855e09eSopenharmony_ci  use nom::{bytes::complete::tag, combinator::map, error::Error, multi::count};
2366855e09eSopenharmony_ci
2376855e09eSopenharmony_ci  // previously, `count()` panicked if the parser had type `O = ()`
2386855e09eSopenharmony_ci  let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ());
2396855e09eSopenharmony_ci  // shouldn't panic
2406855e09eSopenharmony_ci  let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed");
2416855e09eSopenharmony_ci  assert_eq!(result, ("def", vec![(), (), ()]));
2426855e09eSopenharmony_ci}
243