xref: /third_party/rust/crates/nom/tests/issues.rs (revision 6855e09e)
1//#![feature(trace_macros)]
2#![allow(dead_code)]
3#![cfg_attr(feature = "cargo-clippy", allow(redundant_closure))]
4
5use nom::{error::ErrorKind, Err, IResult, Needed};
6
7#[allow(dead_code)]
8struct Range {
9  start: char,
10  end: char,
11}
12
13pub fn take_char(input: &[u8]) -> IResult<&[u8], char> {
14  if !input.is_empty() {
15    Ok((&input[1..], input[0] as char))
16  } else {
17    Err(Err::Incomplete(Needed::new(1)))
18  }
19}
20
21#[cfg(feature = "std")]
22mod parse_int {
23  use nom::HexDisplay;
24  use nom::{
25    character::streaming::{digit1 as digit, space1 as space},
26    combinator::{complete, map, opt},
27    multi::many0,
28    IResult,
29  };
30  use std::str;
31
32  fn parse_ints(input: &[u8]) -> IResult<&[u8], Vec<i32>> {
33    many0(spaces_or_int)(input)
34  }
35
36  fn spaces_or_int(input: &[u8]) -> IResult<&[u8], i32> {
37    println!("{}", input.to_hex(8));
38    let (i, _) = opt(complete(space))(input)?;
39    let (i, res) = map(complete(digit), |x| {
40      println!("x: {:?}", x);
41      let result = str::from_utf8(x).unwrap();
42      println!("Result: {}", result);
43      println!("int is empty?: {}", x.is_empty());
44      match result.parse() {
45        Ok(i) => i,
46        Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
47      }
48    })(i)?;
49
50    Ok((i, res))
51  }
52
53  #[test]
54  fn issue_142() {
55    let subject = parse_ints(&b"12 34 5689a"[..]);
56    let expected = Ok((&b"a"[..], vec![12, 34, 5689]));
57    assert_eq!(subject, expected);
58
59    let subject = parse_ints(&b"12 34 5689 "[..]);
60    let expected = Ok((&b" "[..], vec![12, 34, 5689]));
61    assert_eq!(subject, expected)
62  }
63}
64
65#[test]
66fn usize_length_bytes_issue() {
67  use nom::multi::length_data;
68  use nom::number::streaming::be_u16;
69  let _: IResult<&[u8], &[u8], (&[u8], ErrorKind)> = length_data(be_u16)(b"012346");
70}
71
72#[test]
73fn take_till_issue() {
74  use nom::bytes::streaming::take_till;
75
76  fn nothing(i: &[u8]) -> IResult<&[u8], &[u8]> {
77    take_till(|_| true)(i)
78  }
79
80  assert_eq!(nothing(b""), Err(Err::Incomplete(Needed::new(1))));
81  assert_eq!(nothing(b"abc"), Ok((&b"abc"[..], &b""[..])));
82}
83
84#[test]
85fn issue_655() {
86  use nom::character::streaming::{line_ending, not_line_ending};
87  fn twolines(i: &str) -> IResult<&str, (&str, &str)> {
88    let (i, l1) = not_line_ending(i)?;
89    let (i, _) = line_ending(i)?;
90    let (i, l2) = not_line_ending(i)?;
91    let (i, _) = line_ending(i)?;
92
93    Ok((i, (l1, l2)))
94  }
95
96  assert_eq!(twolines("foo\nbar\n"), Ok(("", ("foo", "bar"))));
97  assert_eq!(twolines("féo\nbar\n"), Ok(("", ("féo", "bar"))));
98  assert_eq!(twolines("foé\nbar\n"), Ok(("", ("foé", "bar"))));
99  assert_eq!(twolines("foé\r\nbar\n"), Ok(("", ("foé", "bar"))));
100}
101
102#[cfg(feature = "alloc")]
103fn issue_717(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
104  use nom::bytes::complete::{is_not, tag};
105  use nom::multi::separated_list0;
106
107  separated_list0(tag([0x0]), is_not([0x0u8]))(i)
108}
109
110mod issue_647 {
111  use nom::bytes::streaming::tag;
112  use nom::combinator::complete;
113  use nom::multi::separated_list0;
114  use nom::{error::Error, number::streaming::be_f64, Err, IResult};
115  pub type Input<'a> = &'a [u8];
116
117  #[derive(PartialEq, Debug, Clone)]
118  struct Data {
119    c: f64,
120    v: Vec<f64>,
121  }
122
123  fn list<'a, 'b>(
124    input: Input<'a>,
125    _cs: &'b f64,
126  ) -> Result<(Input<'a>, Vec<f64>), Err<Error<&'a [u8]>>> {
127    separated_list0(complete(tag(",")), complete(be_f64))(input)
128  }
129
130  fn data(input: Input<'_>) -> IResult<Input<'_>, Data> {
131    let (i, c) = be_f64(input)?;
132    let (i, _) = tag("\n")(i)?;
133    let (i, v) = list(i, &c)?;
134    Ok((i, Data { c, v }))
135  }
136}
137
138#[test]
139fn issue_848_overflow_incomplete_bits_to_bytes() {
140  fn take(i: &[u8]) -> IResult<&[u8], &[u8]> {
141    use nom::bytes::streaming::take;
142    take(0x2000000000000000_usize)(i)
143  }
144  fn parser(i: &[u8]) -> IResult<&[u8], &[u8]> {
145    use nom::bits::{bits, bytes};
146
147    bits(bytes(take))(i)
148  }
149  assert_eq!(
150    parser(&b""[..]),
151    Err(Err::Failure(nom::error_position!(
152      &b""[..],
153      ErrorKind::TooLarge
154    )))
155  );
156}
157
158#[test]
159fn issue_942() {
160  use nom::error::{ContextError, ParseError};
161  pub fn parser<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
162    i: &'a str,
163  ) -> IResult<&'a str, usize, E> {
164    use nom::{character::complete::char, error::context, multi::many0_count};
165    many0_count(context("char_a", char('a')))(i)
166  }
167  assert_eq!(parser::<()>("aaa"), Ok(("", 3)));
168}
169
170#[test]
171fn issue_many_m_n_with_zeros() {
172  use nom::character::complete::char;
173  use nom::multi::many_m_n;
174  let mut parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
175  assert_eq!(parser("aaa"), Ok(("aaa", vec![])));
176}
177
178#[test]
179fn issue_1027_convert_error_panic_nonempty() {
180  use nom::character::complete::char;
181  use nom::error::{convert_error, VerboseError};
182  use nom::sequence::pair;
183
184  let input = "a";
185
186  let result: IResult<_, _, VerboseError<&str>> = pair(char('a'), char('b'))(input);
187  let err = match result.unwrap_err() {
188    Err::Error(e) => e,
189    _ => unreachable!(),
190  };
191
192  let msg = convert_error(input, err);
193  assert_eq!(
194    msg,
195    "0: at line 1:\na\n ^\nexpected \'b\', got end of input\n\n"
196  );
197}
198
199#[test]
200fn issue_1231_bits_expect_fn_closure() {
201  use nom::bits::{bits, complete::take};
202  use nom::error::Error;
203  use nom::sequence::tuple;
204  pub fn example(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
205    bits::<_, _, Error<_>, _, _>(tuple((take(1usize), take(1usize))))(input)
206  }
207  assert_eq!(example(&[0xff]), Ok((&b""[..], (1, 1))));
208}
209
210#[test]
211fn issue_1282_findtoken_char() {
212  use nom::character::complete::one_of;
213  use nom::error::Error;
214  let parser = one_of::<_, _, Error<_>>(&['a', 'b', 'c'][..]);
215  assert_eq!(parser("aaa"), Ok(("aa", 'a')));
216}
217
218#[test]
219fn issue_1459_clamp_capacity() {
220  use nom::character::complete::char;
221
222  // shouldn't panic
223  use nom::multi::many_m_n;
224  let mut parser = many_m_n::<_, _, (), _>(usize::MAX, usize::MAX, char('a'));
225  assert_eq!(parser("a"), Err(nom::Err::Error(())));
226
227  // shouldn't panic
228  use nom::multi::count;
229  let mut parser = count::<_, _, (), _>(char('a'), usize::MAX);
230  assert_eq!(parser("a"), Err(nom::Err::Error(())));
231}
232
233#[test]
234fn issue_1617_count_parser_returning_zero_size() {
235  use nom::{bytes::complete::tag, combinator::map, error::Error, multi::count};
236
237  // previously, `count()` panicked if the parser had type `O = ()`
238  let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ());
239  // shouldn't panic
240  let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed");
241  assert_eq!(result, ("def", vec![(), (), ()]));
242}
243