nom/bytes/
streaming.rs

1//! Parsers recognizing bytes streams, streaming version
2
3use core::marker::PhantomData;
4
5use crate::error::ParseError;
6use crate::internal::{IResult, Parser};
7use crate::traits::{Compare, FindSubstring, FindToken, ToUsize};
8use crate::Emit;
9use crate::Input;
10use crate::OutputM;
11use crate::Streaming;
12
13/// Recognizes a pattern.
14///
15/// The input data will be compared to the tag combinator's argument and will return the part of
16/// the input that matches the argument.
17/// # Example
18/// ```rust
19/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
20/// use nom::bytes::streaming::tag;
21///
22/// fn parser(s: &str) -> IResult<&str, &str> {
23///   tag("Hello")(s)
24/// }
25///
26/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
27/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
28/// assert_eq!(parser("S"), Err(Err::Error(Error::new("S", ErrorKind::Tag))));
29/// assert_eq!(parser("H"), Err(Err::Incomplete(Needed::new(4))));
30/// ```
31pub fn tag<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
32where
33  I: Input + Compare<T>,
34  T: Input + Clone,
35{
36  move |i: I| {
37    let mut parser = super::Tag {
38      tag: tag.clone(),
39      e: PhantomData,
40    };
41
42    parser.process::<OutputM<Emit, Emit, Streaming>>(i)
43  }
44}
45
46/// Recognizes a case insensitive pattern.
47///
48/// The input data will be compared to the tag combinator's argument and will return the part of
49/// the input that matches the argument with no regard to case.
50/// # Example
51/// ```rust
52/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
53/// use nom::bytes::streaming::tag_no_case;
54///
55/// fn parser(s: &str) -> IResult<&str, &str> {
56///   tag_no_case("hello")(s)
57/// }
58///
59/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
60/// assert_eq!(parser("hello, World!"), Ok((", World!", "hello")));
61/// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO")));
62/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
63/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5))));
64/// ```
65pub fn tag_no_case<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
66where
67  I: Input + Compare<T>,
68  T: Input + Clone,
69{
70  move |i: I| {
71    let mut parser = super::TagNoCase {
72      tag: tag.clone(),
73      e: PhantomData,
74    };
75
76    parser.process::<OutputM<Emit, Emit, Streaming>>(i)
77  }
78}
79
80/// Parse till certain characters are met.
81///
82/// The parser will return the longest slice till one of the characters of the combinator's argument are met.
83///
84/// It doesn't consume the matched character.
85///
86/// It will return a `Err::Incomplete(Needed::new(1))` if the pattern wasn't met.
87/// # Example
88/// ```rust
89/// # use nom::{Err, error::ErrorKind, Needed, IResult};
90/// use nom::bytes::streaming::is_not;
91///
92/// fn not_space(s: &str) -> IResult<&str, &str> {
93///   is_not(" \t\r\n")(s)
94/// }
95///
96/// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,")));
97/// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes")));
98/// assert_eq!(not_space("Nospace"), Err(Err::Incomplete(Needed::new(1))));
99/// assert_eq!(not_space(""), Err(Err::Incomplete(Needed::new(1))));
100/// ```
101pub fn is_not<T, I, Error: ParseError<I>>(arr: T) -> impl FnMut(I) -> IResult<I, I, Error>
102where
103  I: Input,
104  T: FindToken<<I as Input>::Item>,
105{
106  let mut parser = super::is_not(arr);
107
108  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
109}
110
111/// Returns the longest slice of the matches the pattern.
112///
113/// The parser will return the longest slice consisting of the characters in provided in the
114/// combinator's argument.
115///
116/// # Streaming specific
117/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern wasn't met
118/// or if the pattern reaches the end of the input.
119/// # Example
120/// ```rust
121/// # use nom::{Err, error::ErrorKind, Needed, IResult};
122/// use nom::bytes::streaming::is_a;
123///
124/// fn hex(s: &str) -> IResult<&str, &str> {
125///   is_a("1234567890ABCDEF")(s)
126/// }
127///
128/// assert_eq!(hex("123 and voila"), Ok((" and voila", "123")));
129/// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF")));
130/// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE")));
131/// assert_eq!(hex("D15EA5E"), Err(Err::Incomplete(Needed::new(1))));
132/// assert_eq!(hex(""), Err(Err::Incomplete(Needed::new(1))));
133/// ```
134pub fn is_a<T, I, Error: ParseError<I>>(arr: T) -> impl FnMut(I) -> IResult<I, I, Error>
135where
136  I: Input,
137  T: FindToken<<I as Input>::Item>,
138{
139  let mut parser = super::is_a(arr);
140
141  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
142}
143
144/// Returns the longest input slice (if any) that matches the predicate.
145///
146/// The parser will return the longest slice that matches the given predicate *(a function that
147/// takes the input and returns a bool)*.
148///
149/// # Streaming Specific
150/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern reaches the end of the input.
151/// # Example
152/// ```rust
153/// # use nom::{Err, error::ErrorKind, Needed, IResult};
154/// use nom::bytes::streaming::take_while;
155/// use nom::AsChar;
156///
157/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
158///   take_while(AsChar::is_alpha)(s)
159/// }
160///
161/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
162/// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..])));
163/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
164/// assert_eq!(alpha(b""), Err(Err::Incomplete(Needed::new(1))));
165/// ```
166pub fn take_while<F, I, Error: ParseError<I>>(cond: F) -> impl FnMut(I) -> IResult<I, I, Error>
167where
168  I: Input,
169  F: Fn(<I as Input>::Item) -> bool,
170{
171  let mut parser = super::take_while(cond);
172
173  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
174}
175
176/// Returns the longest (at least 1) input slice that matches the predicate.
177///
178/// The parser will return the longest slice that matches the given predicate *(a function that
179/// takes the input and returns a bool)*.
180///
181/// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met.
182///
183/// # Streaming Specific
184/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` or if the pattern reaches the end of the input.
185///
186/// # Example
187/// ```rust
188/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
189/// use nom::bytes::streaming::take_while1;
190/// use nom::AsChar;
191///
192/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
193///   take_while1(AsChar::is_alpha)(s)
194/// }
195///
196/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
197/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
198/// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1))));
199/// ```
200pub fn take_while1<F, I, Error: ParseError<I>>(cond: F) -> impl FnMut(I) -> IResult<I, I, Error>
201where
202  I: Input,
203  F: Fn(<I as Input>::Item) -> bool,
204{
205  let mut parser = super::take_while1(cond);
206
207  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
208}
209
210/// Returns the longest (m <= len <= n) input slice  that matches the predicate.
211///
212/// The parser will return the longest slice that matches the given predicate *(a function that
213/// takes the input and returns a bool)*.
214///
215/// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met.
216/// # Streaming Specific
217/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))`  if the pattern reaches the end of the input or is too short.
218///
219/// # Example
220/// ```rust
221/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
222/// use nom::bytes::streaming::take_while_m_n;
223/// use nom::AsChar;
224///
225/// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
226///   take_while_m_n(3, 6, AsChar::is_alpha)(s)
227/// }
228///
229/// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
230/// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..])));
231/// assert_eq!(short_alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
232/// assert_eq!(short_alpha(b"ed"), Err(Err::Incomplete(Needed::new(1))));
233/// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN))));
234/// ```
235pub fn take_while_m_n<F, I, Error: ParseError<I>>(
236  m: usize,
237  n: usize,
238  cond: F,
239) -> impl FnMut(I) -> IResult<I, I, Error>
240where
241  I: Input,
242  F: Fn(<I as Input>::Item) -> bool,
243{
244  let mut parser = super::take_while_m_n(m, n, cond);
245
246  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
247}
248
249/// Returns the longest input slice (if any) till a predicate is met.
250///
251/// The parser will return the longest slice till the given predicate *(a function that
252/// takes the input and returns a bool)*.
253///
254/// # Streaming Specific
255/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the
256/// end of input or if there was not match.
257///
258/// # Example
259/// ```rust
260/// # use nom::{Err, error::ErrorKind, Needed, IResult};
261/// use nom::bytes::streaming::take_till;
262///
263/// fn till_colon(s: &str) -> IResult<&str, &str> {
264///   take_till(|c| c == ':')(s)
265/// }
266///
267/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
268/// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed
269/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
270/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
271/// ```
272#[allow(clippy::redundant_closure)]
273pub fn take_till<F, I, Error: ParseError<I>>(cond: F) -> impl FnMut(I) -> IResult<I, I, Error>
274where
275  I: Input,
276  F: Fn(<I as Input>::Item) -> bool,
277{
278  let mut parser = super::take_till(cond);
279
280  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
281}
282
283/// Returns the longest (at least 1) input slice till a predicate is met.
284///
285/// The parser will return the longest slice till the given predicate *(a function that
286/// takes the input and returns a bool)*.
287///
288/// # Streaming Specific
289/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the
290/// end of input or if there was not match.
291/// # Example
292/// ```rust
293/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
294/// use nom::bytes::streaming::take_till1;
295///
296/// fn till_colon(s: &str) -> IResult<&str, &str> {
297///   take_till1(|c| c == ':')(s)
298/// }
299///
300/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
301/// assert_eq!(till_colon(":empty matched"), Err(Err::Error(Error::new(":empty matched", ErrorKind::TakeTill1))));
302/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
303/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
304/// ```
305#[allow(clippy::redundant_closure)]
306pub fn take_till1<F, I, Error: ParseError<I>>(cond: F) -> impl FnMut(I) -> IResult<I, I, Error>
307where
308  I: Input,
309  F: Fn(<I as Input>::Item) -> bool,
310{
311  let mut parser = super::take_till1(cond);
312
313  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
314}
315
316/// Returns an input slice containing the first N input elements (Input[..N]).
317///
318/// # Streaming Specific
319/// *Streaming version* if the input has less than N elements, `take` will
320/// return a `Err::Incomplete(Needed::new(M))` where M is the number of
321/// additional bytes the parser would need to succeed.
322/// It is well defined for `&[u8]` as the number of elements is the byte size,
323/// but for types like `&str`, we cannot know how many bytes correspond for
324/// the next few chars, so the result will be `Err::Incomplete(Needed::Unknown)`
325///
326/// # Example
327/// ```rust
328/// # use nom::{Err, error::ErrorKind, Needed, IResult};
329/// use nom::bytes::streaming::take;
330///
331/// fn take6(s: &str) -> IResult<&str, &str> {
332///   take(6usize)(s)
333/// }
334///
335/// assert_eq!(take6("1234567"), Ok(("7", "123456")));
336/// assert_eq!(take6("things"), Ok(("", "things")));
337/// assert_eq!(take6("short"), Err(Err::Incomplete(Needed::Unknown)));
338/// ```
339pub fn take<C, I, Error: ParseError<I>>(count: C) -> impl FnMut(I) -> IResult<I, I, Error>
340where
341  I: Input,
342  C: ToUsize,
343{
344  let mut parser = super::take(count);
345
346  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
347}
348
349/// Returns the input slice up to the first occurrence of the pattern.
350///
351/// It doesn't consume the pattern.
352///
353/// # Streaming Specific
354/// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't
355/// contain the pattern or if the input is smaller than the pattern.
356/// # Example
357/// ```rust
358/// # use nom::{Err, error::ErrorKind, Needed, IResult};
359/// use nom::bytes::streaming::take_until;
360///
361/// fn until_eof(s: &str) -> IResult<&str, &str> {
362///   take_until("eof")(s)
363/// }
364///
365/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
366/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown)));
367/// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown)));
368/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
369/// ```
370pub fn take_until<T, I, Error: ParseError<I>>(tag: T) -> impl FnMut(I) -> IResult<I, I, Error>
371where
372  I: Input + FindSubstring<T>,
373  T: Clone,
374{
375  let mut parser = super::take_until(tag);
376
377  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
378}
379
380/// Returns the non empty input slice up to the first occurrence of the pattern.
381///
382/// It doesn't consume the pattern.
383///
384/// # Streaming Specific
385/// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't
386/// contain the pattern or if the input is smaller than the pattern.
387/// # Example
388/// ```rust
389/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
390/// use nom::bytes::streaming::take_until1;
391///
392/// fn until_eof(s: &str) -> IResult<&str, &str> {
393///   take_until1("eof")(s)
394/// }
395///
396/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
397/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown)));
398/// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown)));
399/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
400/// assert_eq!(until_eof("eof"),  Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
401/// ```
402pub fn take_until1<T, I, Error: ParseError<I>>(tag: T) -> impl FnMut(I) -> IResult<I, I, Error>
403where
404  I: Input + FindSubstring<T>,
405  T: Clone,
406{
407  let mut parser = super::take_until1(tag);
408
409  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
410}
411
412/// Matches a byte string with escaped characters.
413///
414/// * The first argument matches the normal characters (it must not accept the control character)
415/// * The second argument is the control character (like `\` in most languages)
416/// * The third argument matches the escaped characters
417/// # Example
418/// ```
419/// # use nom::{Err, error::ErrorKind, Needed, IResult};
420/// # use nom::character::complete::digit1;
421/// use nom::bytes::streaming::escaped;
422/// use nom::character::streaming::one_of;
423///
424/// fn esc(s: &str) -> IResult<&str, &str> {
425///   escaped(digit1, '\\', one_of("\"n\\"))(s)
426/// }
427///
428/// assert_eq!(esc("123;"), Ok((";", "123")));
429/// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34")));
430/// ```
431///
432pub fn escaped<I, Error, F, G>(
433  normal: F,
434  control_char: char,
435  escapable: G,
436) -> impl FnMut(I) -> IResult<I, I, Error>
437where
438  I: Input + Clone + crate::traits::Offset,
439  <I as Input>::Item: crate::traits::AsChar,
440  F: Parser<I, Error = Error>,
441  G: Parser<I, Error = Error>,
442  Error: ParseError<I>,
443{
444  let mut parser = super::escaped(normal, control_char, escapable);
445
446  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
447}
448
449/// Matches a byte string with escaped characters.
450///
451/// * The first argument matches the normal characters (it must not match the control character)
452/// * The second argument is the control character (like `\` in most languages)
453/// * The third argument matches the escaped characters and transforms them
454///
455/// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
456///
457/// ```
458/// # use nom::{Err, error::ErrorKind, Needed, IResult};
459/// # use std::str::from_utf8;
460/// use nom::bytes::streaming::{escaped_transform, tag};
461/// use nom::character::streaming::alpha1;
462/// use nom::branch::alt;
463/// use nom::combinator::value;
464///
465/// fn parser(input: &str) -> IResult<&str, String> {
466///   escaped_transform(
467///     alpha1,
468///     '\\',
469///     alt((
470///       value("\\", tag("\\")),
471///       value("\"", tag("\"")),
472///       value("\n", tag("n")),
473///     ))
474///   )(input)
475/// }
476///
477/// assert_eq!(parser("ab\\\"cd\""), Ok(("\"", String::from("ab\"cd"))));
478/// ```
479#[cfg(feature = "alloc")]
480#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
481pub fn escaped_transform<I, Error, F, G, O1, O2, ExtendItem, Output>(
482  normal: F,
483  control_char: char,
484  transform: G,
485) -> impl FnMut(I) -> IResult<I, Output, Error>
486where
487  I: Clone + crate::traits::Offset + Input,
488  I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
489  O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
490  O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
491  <I as Input>::Item: crate::traits::AsChar,
492  F: Parser<I, Output = O1, Error = Error>,
493  G: Parser<I, Output = O2, Error = Error>,
494  Error: ParseError<I>,
495{
496  let mut parser = super::escaped_transform(normal, control_char, transform);
497
498  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
499}