nom8/bytes/
streaming.rs

1//! Parsers recognizing bytes streams, streaming version
2
3#![allow(deprecated)]
4
5use crate::error::ErrorKind;
6use crate::error::ParseError;
7use crate::input::{
8  Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
9  InputTakeAtPosition, IntoOutput, Slice, ToUsize,
10};
11use crate::lib::std::ops::RangeFrom;
12use crate::lib::std::result::Result::*;
13use crate::IntoOutputIResult;
14use crate::{Err, IResult, Needed, Parser};
15
16pub(crate) fn any<I, E: ParseError<I>>(input: I) -> IResult<I, <I as InputIter>::Item, E>
17where
18  I: InputIter + InputLength + Slice<RangeFrom<usize>>,
19{
20  let mut it = input.iter_indices();
21  match it.next() {
22    None => Err(Err::Incomplete(Needed::new(1))),
23    Some((_, c)) => match it.next() {
24      None => Ok((input.slice(input.input_len()..), c)),
25      Some((idx, _)) => Ok((input.slice(idx..), c)),
26    },
27  }
28}
29
30/// Recognizes a pattern.
31///
32/// The input data will be compared to the tag combinator's argument and will return the part of
33/// the input that matches the argument.
34/// # Example
35/// ```rust
36/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
37/// use nom8::bytes::streaming::tag;
38///
39/// fn parser(s: &str) -> IResult<&str, &str> {
40///   tag("Hello")(s)
41/// }
42///
43/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
44/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
45/// assert_eq!(parser("S"), Err(Err::Error(Error::new("S", ErrorKind::Tag))));
46/// assert_eq!(parser("H"), Err(Err::Incomplete(Needed::new(4))));
47/// ```
48///
49/// **WARNING:** Deprecated, replaced with [`nom8::bytes::tag`][crate::bytes::tag] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
50#[deprecated(
51  since = "8.0.0",
52  note = "Replaced with `nom8::bytes::tag` with input wrapped in `nom8::input::Streaming`"
53)]
54pub fn tag<T, Input, Error: ParseError<Input>>(
55  tag: T,
56) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
57where
58  Input: InputTake + InputLength + Compare<T>,
59  Input: IntoOutput,
60  T: InputLength + Clone,
61{
62  move |i: Input| tag_internal(i, tag.clone())
63}
64
65pub(crate) fn tag_internal<T, Input, Error: ParseError<Input>>(
66  i: Input,
67  t: T,
68) -> IResult<Input, <Input as IntoOutput>::Output, Error>
69where
70  Input: InputTake + InputLength + Compare<T>,
71  Input: IntoOutput,
72  T: InputLength,
73{
74  let tag_len = t.input_len();
75
76  let res: IResult<_, _, Error> = match i.compare(t) {
77    CompareResult::Ok => Ok(i.take_split(tag_len)),
78    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
79    CompareResult::Error => {
80      let e: ErrorKind = ErrorKind::Tag;
81      Err(Err::Error(Error::from_error_kind(i, e)))
82    }
83  };
84  res.into_output()
85}
86
87/// Recognizes a case insensitive pattern.
88///
89/// The input data will be compared to the tag combinator's argument and will return the part of
90/// the input that matches the argument with no regard to case.
91/// # Example
92/// ```rust
93/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
94/// use nom8::bytes::streaming::tag_no_case;
95///
96/// fn parser(s: &str) -> IResult<&str, &str> {
97///   tag_no_case("hello")(s)
98/// }
99///
100/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
101/// assert_eq!(parser("hello, World!"), Ok((", World!", "hello")));
102/// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO")));
103/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
104/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5))));
105/// ```
106///
107/// **WARNING:** Deprecated, replaced with [`nom8::bytes::tag_no_case`][crate::bytes::tag_no_case] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
108#[deprecated(
109  since = "8.0.0",
110  note = "Replaced with `nom8::bytes::tag_no_case` with input wrapped in `nom8::input::Streaming`"
111)]
112pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
113  tag: T,
114) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
115where
116  Input: InputTake + InputLength + Compare<T>,
117  Input: IntoOutput,
118  T: InputLength + Clone,
119{
120  move |i: Input| tag_no_case_internal(i, tag.clone())
121}
122
123pub(crate) fn tag_no_case_internal<T, Input, Error: ParseError<Input>>(
124  i: Input,
125  t: T,
126) -> IResult<Input, <Input as IntoOutput>::Output, Error>
127where
128  Input: InputTake + InputLength + Compare<T>,
129  Input: IntoOutput,
130  T: InputLength,
131{
132  let tag_len = t.input_len();
133
134  let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
135    CompareResult::Ok => Ok(i.take_split(tag_len)),
136    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
137    CompareResult::Error => {
138      let e: ErrorKind = ErrorKind::Tag;
139      Err(Err::Error(Error::from_error_kind(i, e)))
140    }
141  };
142  res.into_output()
143}
144
145pub(crate) fn one_of_internal<I, T, E: ParseError<I>>(
146  input: I,
147  list: &T,
148) -> IResult<I, <I as InputIter>::Item, E>
149where
150  I: Slice<RangeFrom<usize>> + InputIter + InputLength,
151  <I as InputIter>::Item: Copy,
152  T: FindToken<<I as InputIter>::Item>,
153{
154  let mut it = input.iter_indices();
155  match it.next() {
156    Some((_, c)) if list.find_token(c) => match it.next() {
157      None => Ok((input.slice(input.input_len()..), c)),
158      Some((idx, _)) => Ok((input.slice(idx..), c)),
159    },
160    Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::OneOf))),
161    None => Err(Err::Incomplete(Needed::new(1))),
162  }
163}
164
165pub(crate) fn none_of_internal<I, T, E: ParseError<I>>(
166  input: I,
167  list: &T,
168) -> IResult<I, <I as InputIter>::Item, E>
169where
170  I: Slice<RangeFrom<usize>> + InputIter + InputLength,
171  <I as InputIter>::Item: Copy,
172  T: FindToken<<I as InputIter>::Item>,
173{
174  let mut it = input.iter_indices();
175  match it.next() {
176    Some((_, c)) if !list.find_token(c) => match it.next() {
177      None => Ok((input.slice(input.input_len()..), c)),
178      Some((idx, _)) => Ok((input.slice(idx..), c)),
179    },
180    Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::NoneOf))),
181    None => Err(Err::Incomplete(Needed::new(1))),
182  }
183}
184
185/// Parse till certain characters are met.
186///
187/// The parser will return the longest slice till one of the characters of the combinator's argument are met.
188///
189/// It doesn't consume the matched character.
190///
191/// It will return a `Err::Incomplete(Needed::new(1))` if the pattern wasn't met.
192/// # Example
193/// ```rust
194/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
195/// use nom8::bytes::streaming::is_not;
196///
197/// fn not_space(s: &str) -> IResult<&str, &str> {
198///   is_not(" \t\r\n")(s)
199/// }
200///
201/// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,")));
202/// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes")));
203/// assert_eq!(not_space("Nospace"), Err(Err::Incomplete(Needed::new(1))));
204/// assert_eq!(not_space(""), Err(Err::Incomplete(Needed::new(1))));
205/// ```
206///
207/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_till1`][crate::bytes::take_till1] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
208#[deprecated(
209  since = "8.0.0",
210  note = "Replaced with `nom8::bytes::take_till1` with input wrapped in `nom8::input::Streaming`"
211)]
212pub fn is_not<T, Input, Error: ParseError<Input>>(
213  arr: T,
214) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
215where
216  Input: InputTakeAtPosition,
217  Input: IntoOutput,
218  T: FindToken<<Input as InputTakeAtPosition>::Item>,
219{
220  move |i: Input| is_not_internal(i, &arr)
221}
222
223pub(crate) fn is_not_internal<T, Input, Error: ParseError<Input>>(
224  i: Input,
225  arr: &T,
226) -> IResult<Input, <Input as IntoOutput>::Output, Error>
227where
228  Input: InputTakeAtPosition,
229  Input: IntoOutput,
230  T: FindToken<<Input as InputTakeAtPosition>::Item>,
231{
232  let e: ErrorKind = ErrorKind::IsNot;
233  i.split_at_position1_streaming(|c| arr.find_token(c), e)
234    .into_output()
235}
236
237/// Returns the longest slice of the matches the pattern.
238///
239/// The parser will return the longest slice consisting of the characters in provided in the
240/// combinator's argument.
241///
242/// # Streaming specific
243/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern wasn't met
244/// or if the pattern reaches the end of the input.
245/// # Example
246/// ```rust
247/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
248/// use nom8::bytes::streaming::is_a;
249///
250/// fn hex(s: &str) -> IResult<&str, &str> {
251///   is_a("1234567890ABCDEF")(s)
252/// }
253///
254/// assert_eq!(hex("123 and voila"), Ok((" and voila", "123")));
255/// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF")));
256/// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE")));
257/// assert_eq!(hex("D15EA5E"), Err(Err::Incomplete(Needed::new(1))));
258/// assert_eq!(hex(""), Err(Err::Incomplete(Needed::new(1))));
259/// ```
260///
261/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_while1`][crate::bytes::take_while1] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
262#[deprecated(
263  since = "8.0.0",
264  note = "Replaced with `nom8::bytes::take_while1` with input wrapped in `nom8::input::Streaming`"
265)]
266pub fn is_a<T, Input, Error: ParseError<Input>>(
267  arr: T,
268) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
269where
270  Input: InputTakeAtPosition,
271  Input: IntoOutput,
272  T: FindToken<<Input as InputTakeAtPosition>::Item>,
273{
274  move |i: Input| is_a_internal(i, &arr)
275}
276
277pub(crate) fn is_a_internal<T, Input, Error: ParseError<Input>>(
278  i: Input,
279  arr: &T,
280) -> IResult<Input, <Input as IntoOutput>::Output, Error>
281where
282  Input: InputTakeAtPosition,
283  Input: IntoOutput,
284  T: FindToken<<Input as InputTakeAtPosition>::Item>,
285{
286  let e: ErrorKind = ErrorKind::IsA;
287  i.split_at_position1_streaming(|c| !arr.find_token(c), e)
288    .into_output()
289}
290
291/// Returns the longest input slice (if any) that matches the predicate.
292///
293/// The parser will return the longest slice that matches the given predicate *(a function that
294/// takes the input and returns a bool)*.
295///
296/// # Streaming Specific
297/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern reaches the end of the input.
298/// # Example
299/// ```rust
300/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
301/// use nom8::bytes::streaming::take_while;
302/// use nom8::input::AsChar;
303///
304/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
305///   take_while(AsChar::is_alpha)(s)
306/// }
307///
308/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
309/// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..])));
310/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
311/// assert_eq!(alpha(b""), Err(Err::Incomplete(Needed::new(1))));
312/// ```
313///
314/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_while`][crate::bytes::take_while] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
315#[deprecated(
316  since = "8.0.0",
317  note = "Replaced with `nom8::bytes::take_while` with input wrapped in `nom8::input::Streaming`"
318)]
319pub fn take_while<T, Input, Error: ParseError<Input>>(
320  list: T,
321) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
322where
323  Input: InputTakeAtPosition,
324  Input: IntoOutput,
325  T: FindToken<<Input as InputTakeAtPosition>::Item>,
326{
327  move |i: Input| take_while_internal(i, &list)
328}
329
330pub(crate) fn take_while_internal<T, Input, Error: ParseError<Input>>(
331  i: Input,
332  list: &T,
333) -> IResult<Input, <Input as IntoOutput>::Output, Error>
334where
335  Input: InputTakeAtPosition,
336  Input: IntoOutput,
337  T: FindToken<<Input as InputTakeAtPosition>::Item>,
338{
339  i.split_at_position_streaming(|c| !list.find_token(c))
340    .into_output()
341}
342
343/// Returns the longest (at least 1) input slice that matches the predicate.
344///
345/// The parser will return the longest slice that matches the given predicate *(a function that
346/// takes the input and returns a bool)*.
347///
348/// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met.
349///
350/// # Streaming Specific
351/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` or if the pattern reaches the end of the input.
352///
353/// # Example
354/// ```rust
355/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
356/// use nom8::bytes::streaming::take_while1;
357/// use nom8::input::AsChar;
358///
359/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
360///   take_while1(AsChar::is_alpha)(s)
361/// }
362///
363/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
364/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
365/// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1))));
366/// ```
367///
368/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_while1`][crate::bytes::take_while1] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
369#[deprecated(
370  since = "8.0.0",
371  note = "Replaced with `nom8::bytes::take_while1` with input wrapped in `nom8::input::Streaming`"
372)]
373pub fn take_while1<T, Input, Error: ParseError<Input>>(
374  list: T,
375) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
376where
377  Input: InputTakeAtPosition,
378  Input: IntoOutput,
379  T: FindToken<<Input as InputTakeAtPosition>::Item>,
380{
381  move |i: Input| take_while1_internal(i, &list)
382}
383
384pub(crate) fn take_while1_internal<T, Input, Error: ParseError<Input>>(
385  i: Input,
386  list: &T,
387) -> IResult<Input, <Input as IntoOutput>::Output, Error>
388where
389  Input: InputTakeAtPosition,
390  Input: IntoOutput,
391  T: FindToken<<Input as InputTakeAtPosition>::Item>,
392{
393  let e: ErrorKind = ErrorKind::TakeWhile1;
394  i.split_at_position1_streaming(|c| !list.find_token(c), e)
395    .into_output()
396}
397
398/// Returns the longest (m <= len <= n) input slice  that matches the predicate.
399///
400/// The parser will return the longest slice that matches the given predicate *(a function that
401/// takes the input and returns a bool)*.
402///
403/// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met.
404/// # Streaming Specific
405/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))`  if the pattern reaches the end of the input or is too short.
406///
407/// # Example
408/// ```rust
409/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
410/// use nom8::bytes::streaming::take_while_m_n;
411/// use nom8::input::AsChar;
412///
413/// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
414///   take_while_m_n(3, 6, AsChar::is_alpha)(s)
415/// }
416///
417/// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
418/// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..])));
419/// assert_eq!(short_alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
420/// assert_eq!(short_alpha(b"ed"), Err(Err::Incomplete(Needed::new(1))));
421/// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN))));
422/// ```
423///
424/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_while_m_n`][crate::bytes::take_while_m_n] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
425#[deprecated(
426  since = "8.0.0",
427  note = "Replaced with `nom8::bytes::take_while_m_n` with input wrapped in `nom8::input::Streaming`"
428)]
429pub fn take_while_m_n<T, Input, Error: ParseError<Input>>(
430  m: usize,
431  n: usize,
432  list: T,
433) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
434where
435  Input: InputTake + InputIter + InputLength,
436  Input: IntoOutput,
437  T: FindToken<<Input as InputIter>::Item>,
438{
439  move |i: Input| take_while_m_n_internal(i, m, n, &list)
440}
441
442pub(crate) fn take_while_m_n_internal<T, Input, Error: ParseError<Input>>(
443  i: Input,
444  m: usize,
445  n: usize,
446  list: &T,
447) -> IResult<Input, <Input as IntoOutput>::Output, Error>
448where
449  Input: InputTake + InputIter + InputLength,
450  Input: IntoOutput,
451  T: FindToken<<Input as InputIter>::Item>,
452{
453  let input = i;
454
455  match input.position(|c| !list.find_token(c)) {
456    Some(idx) => {
457      if idx >= m {
458        if idx <= n {
459          let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(idx) {
460            Ok(input.take_split(index)).into_output()
461          } else {
462            Err(Err::Error(Error::from_error_kind(
463              input,
464              ErrorKind::TakeWhileMN,
465            )))
466          };
467          res
468        } else {
469          let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(n) {
470            Ok(input.take_split(index)).into_output()
471          } else {
472            Err(Err::Error(Error::from_error_kind(
473              input,
474              ErrorKind::TakeWhileMN,
475            )))
476          };
477          res
478        }
479      } else {
480        let e = ErrorKind::TakeWhileMN;
481        Err(Err::Error(Error::from_error_kind(input, e)))
482      }
483    }
484    None => {
485      let len = input.input_len();
486      if len >= n {
487        match input.slice_index(n) {
488          Ok(index) => Ok(input.take_split(index)).into_output(),
489          Err(_needed) => Err(Err::Error(Error::from_error_kind(
490            input,
491            ErrorKind::TakeWhileMN,
492          ))),
493        }
494      } else {
495        let needed = if m > len { m - len } else { 1 };
496        Err(Err::Incomplete(Needed::new(needed)))
497      }
498    }
499  }
500}
501
502/// Returns the longest input slice (if any) till a predicate is met.
503///
504/// The parser will return the longest slice till the given predicate *(a function that
505/// takes the input and returns a bool)*.
506///
507/// # Streaming Specific
508/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the
509/// end of input or if there was not match.
510///
511/// # Example
512/// ```rust
513/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
514/// use nom8::bytes::streaming::take_till;
515///
516/// fn till_colon(s: &str) -> IResult<&str, &str> {
517///   take_till(|c| c == ':')(s)
518/// }
519///
520/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
521/// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed
522/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
523/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
524/// ```
525///
526/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_till`][crate::bytes::take_till] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
527#[deprecated(
528  since = "8.0.0",
529  note = "Replaced with `nom8::bytes::take_till` with input wrapped in `nom8::input::Streaming`"
530)]
531pub fn take_till<T, Input, Error: ParseError<Input>>(
532  list: T,
533) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
534where
535  Input: InputTakeAtPosition,
536  Input: IntoOutput,
537  T: FindToken<<Input as InputTakeAtPosition>::Item>,
538{
539  move |i: Input| take_till_internal(i, &list)
540}
541
542pub(crate) fn take_till_internal<T, Input, Error: ParseError<Input>>(
543  i: Input,
544  list: &T,
545) -> IResult<Input, <Input as IntoOutput>::Output, Error>
546where
547  Input: InputTakeAtPosition,
548  Input: IntoOutput,
549  T: FindToken<<Input as InputTakeAtPosition>::Item>,
550{
551  i.split_at_position_streaming(|c| list.find_token(c))
552    .into_output()
553}
554
555/// Returns the longest (at least 1) input slice till a predicate is met.
556///
557/// The parser will return the longest slice till the given predicate *(a function that
558/// takes the input and returns a bool)*.
559///
560/// # Streaming Specific
561/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the
562/// end of input or if there was not match.
563/// # Example
564/// ```rust
565/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
566/// use nom8::bytes::streaming::take_till1;
567///
568/// fn till_colon(s: &str) -> IResult<&str, &str> {
569///   take_till1(|c| c == ':')(s)
570/// }
571///
572/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
573/// assert_eq!(till_colon(":empty matched"), Err(Err::Error(Error::new(":empty matched", ErrorKind::TakeTill1))));
574/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
575/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
576/// ```
577///
578/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_till1`][crate::bytes::take_till1] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
579#[deprecated(
580  since = "8.0.0",
581  note = "Replaced with `nom8::bytes::take_till1` with input wrapped in `nom8::input::Streaming`"
582)]
583pub fn take_till1<T, Input, Error: ParseError<Input>>(
584  list: T,
585) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
586where
587  Input: InputTakeAtPosition,
588  Input: IntoOutput,
589  T: FindToken<<Input as InputTakeAtPosition>::Item>,
590{
591  move |i: Input| take_till1_internal(i, &list)
592}
593
594pub(crate) fn take_till1_internal<T, Input, Error: ParseError<Input>>(
595  i: Input,
596  list: &T,
597) -> IResult<Input, <Input as IntoOutput>::Output, Error>
598where
599  Input: InputTakeAtPosition,
600  Input: IntoOutput,
601  T: FindToken<<Input as InputTakeAtPosition>::Item>,
602{
603  let e: ErrorKind = ErrorKind::TakeTill1;
604  i.split_at_position1_streaming(|c| list.find_token(c), e)
605    .into_output()
606}
607
608/// Returns an input slice containing the first N input elements (Input[..N]).
609///
610/// # Streaming Specific
611/// *Streaming version* if the input has less than N elements, `take` will
612/// return a `Err::Incomplete(Needed::new(M))` where M is the number of
613/// additional bytes the parser would need to succeed.
614/// It is well defined for `&[u8]` as the number of elements is the byte size,
615/// but for types like `&str`, we cannot know how many bytes correspond for
616/// the next few chars, so the result will be `Err::Incomplete(Needed::Unknown)`
617///
618/// # Example
619/// ```rust
620/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
621/// use nom8::bytes::streaming::take;
622///
623/// fn take6(s: &str) -> IResult<&str, &str> {
624///   take(6usize)(s)
625/// }
626///
627/// assert_eq!(take6("1234567"), Ok(("7", "123456")));
628/// assert_eq!(take6("things"), Ok(("", "things")));
629/// assert_eq!(take6("short"), Err(Err::Incomplete(Needed::Unknown)));
630/// ```
631///
632/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take`][crate::bytes::take] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
633#[deprecated(
634  since = "8.0.0",
635  note = "Replaced with `nom8::bytes::take` with input wrapped in `nom8::input::Streaming`"
636)]
637pub fn take<C, Input, Error: ParseError<Input>>(
638  count: C,
639) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
640where
641  Input: InputIter + InputTake + InputLength,
642  Input: IntoOutput,
643  C: ToUsize,
644{
645  let c = count.to_usize();
646  move |i: Input| take_internal(i, c)
647}
648
649pub(crate) fn take_internal<Input, Error: ParseError<Input>>(
650  i: Input,
651  c: usize,
652) -> IResult<Input, <Input as IntoOutput>::Output, Error>
653where
654  Input: InputIter + InputTake + InputLength,
655  Input: IntoOutput,
656{
657  match i.slice_index(c) {
658    Err(i) => Err(Err::Incomplete(i)),
659    Ok(index) => Ok(i.take_split(index)).into_output(),
660  }
661}
662
663/// Returns the input slice up to the first occurrence of the pattern.
664///
665/// It doesn't consume the pattern.
666///
667/// # Streaming Specific
668/// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't
669/// contain the pattern or if the input is smaller than the pattern.
670/// # Example
671/// ```rust
672/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
673/// use nom8::bytes::streaming::take_until;
674///
675/// fn until_eof(s: &str) -> IResult<&str, &str> {
676///   take_until("eof")(s)
677/// }
678///
679/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
680/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown)));
681/// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown)));
682/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
683/// ```
684///
685/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_until`][crate::bytes::take_until] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
686#[deprecated(
687  since = "8.0.0",
688  note = "Replaced with `nom8::bytes::take_until` with input wrapped in `nom8::input::Streaming`"
689)]
690pub fn take_until<T, Input, Error: ParseError<Input>>(
691  tag: T,
692) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
693where
694  Input: InputTake + InputLength + FindSubstring<T>,
695  Input: IntoOutput,
696  T: Clone,
697{
698  move |i: Input| take_until_internal(i, tag.clone())
699}
700
701pub(crate) fn take_until_internal<T, Input, Error: ParseError<Input>>(
702  i: Input,
703  t: T,
704) -> IResult<Input, <Input as IntoOutput>::Output, Error>
705where
706  Input: InputTake + InputLength + FindSubstring<T>,
707  Input: IntoOutput,
708{
709  let res: IResult<_, _, Error> = match i.find_substring(t) {
710    None => Err(Err::Incomplete(Needed::Unknown)),
711    Some(index) => Ok(i.take_split(index)),
712  };
713  res.into_output()
714}
715
716/// Returns the non empty input slice up to the first occurrence of the pattern.
717///
718/// It doesn't consume the pattern.
719///
720/// # Streaming Specific
721/// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't
722/// contain the pattern or if the input is smaller than the pattern.
723/// # Example
724/// ```rust
725/// # use nom8::{Err, error::{Error, ErrorKind}, Needed, IResult};
726/// use nom8::bytes::streaming::take_until1;
727///
728/// fn until_eof(s: &str) -> IResult<&str, &str> {
729///   take_until1("eof")(s)
730/// }
731///
732/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
733/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown)));
734/// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown)));
735/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
736/// assert_eq!(until_eof("eof"),  Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
737/// ```
738///
739/// **WARNING:** Deprecated, replaced with [`nom8::bytes::take_until1`][crate::bytes::take_until1] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
740#[deprecated(
741  since = "8.0.0",
742  note = "Replaced with `nom8::bytes::take_until1` with input wrapped in `nom8::input::Streaming`"
743)]
744pub fn take_until1<T, Input, Error: ParseError<Input>>(
745  tag: T,
746) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
747where
748  Input: InputTake + InputLength + FindSubstring<T>,
749  Input: IntoOutput,
750  T: Clone,
751{
752  move |i: Input| take_until1_internal(i, tag.clone())
753}
754
755pub(crate) fn take_until1_internal<T, Input, Error: ParseError<Input>>(
756  i: Input,
757  t: T,
758) -> IResult<Input, <Input as IntoOutput>::Output, Error>
759where
760  Input: InputTake + InputLength + FindSubstring<T>,
761  Input: IntoOutput,
762{
763  let res: IResult<_, _, Error> = match i.find_substring(t) {
764    None => Err(Err::Incomplete(Needed::Unknown)),
765    Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
766    Some(index) => Ok(i.take_split(index)),
767  };
768  res.into_output()
769}
770
771/// Matches a byte string with escaped characters.
772///
773/// * The first argument matches the normal characters (it must not accept the control character)
774/// * The second argument is the control character (like `\` in most languages)
775/// * The third argument matches the escaped characters
776/// # Example
777/// ```
778/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
779/// # use nom8::character::streaming::digit1;
780/// use nom8::bytes::streaming::escaped;
781/// use nom8::character::streaming::one_of;
782///
783/// fn esc(s: &str) -> IResult<&str, &str> {
784///   escaped(digit1, '\\', one_of("\"n\\"))(s)
785/// }
786///
787/// assert_eq!(esc("123;"), Ok((";", "123")));
788/// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34")));
789/// ```
790///
791///
792/// **WARNING:** Deprecated, replaced with [`nom8::bytes::escaped`][crate::bytes::escaped] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
793#[deprecated(
794  since = "8.0.0",
795  note = "Replaced with `nom8::bytes::escaped` with input wrapped in `nom8::input::Streaming`"
796)]
797pub fn escaped<Input, Error, F, G, O1, O2>(
798  mut normal: F,
799  control_char: char,
800  mut escapable: G,
801) -> impl FnMut(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
802where
803  Input: Clone
804    + crate::input::Offset
805    + InputLength
806    + InputTake
807    + InputTakeAtPosition
808    + Slice<RangeFrom<usize>>
809    + InputIter,
810  Input: IntoOutput,
811  <Input as InputIter>::Item: crate::input::AsChar,
812  F: Parser<Input, O1, Error>,
813  G: Parser<Input, O2, Error>,
814  Error: ParseError<Input>,
815{
816  move |input: Input| escaped_internal(input, &mut normal, control_char, &mut escapable)
817}
818
819pub(crate) fn escaped_internal<Input, Error, F, G, O1, O2>(
820  input: Input,
821  normal: &mut F,
822  control_char: char,
823  escapable: &mut G,
824) -> IResult<Input, <Input as IntoOutput>::Output, Error>
825where
826  Input: Clone
827    + crate::input::Offset
828    + InputLength
829    + InputTake
830    + InputTakeAtPosition
831    + Slice<RangeFrom<usize>>
832    + InputIter,
833  Input: IntoOutput,
834  <Input as InputIter>::Item: crate::input::AsChar,
835  F: Parser<Input, O1, Error>,
836  G: Parser<Input, O2, Error>,
837  Error: ParseError<Input>,
838{
839  use crate::input::AsChar;
840
841  let mut i = input.clone();
842
843  while i.input_len() > 0 {
844    let current_len = i.input_len();
845
846    match normal.parse(i.clone()) {
847      Ok((i2, _)) => {
848        if i2.input_len() == 0 {
849          return Err(Err::Incomplete(Needed::Unknown));
850        } else if i2.input_len() == current_len {
851          let index = input.offset(&i2);
852          return Ok(input.take_split(index)).into_output();
853        } else {
854          i = i2;
855        }
856      }
857      Err(Err::Error(_)) => {
858        // unwrap() should be safe here since index < $i.input_len()
859        if i.iter_elements().next().unwrap().as_char() == control_char {
860          let next = control_char.len_utf8();
861          if next >= i.input_len() {
862            return Err(Err::Incomplete(Needed::new(1)));
863          } else {
864            match escapable.parse(i.slice(next..)) {
865              Ok((i2, _)) => {
866                if i2.input_len() == 0 {
867                  return Err(Err::Incomplete(Needed::Unknown));
868                } else {
869                  i = i2;
870                }
871              }
872              Err(e) => return Err(e),
873            }
874          }
875        } else {
876          let index = input.offset(&i);
877          return Ok(input.take_split(index)).into_output();
878        }
879      }
880      Err(e) => {
881        return Err(e);
882      }
883    }
884  }
885
886  Err(Err::Incomplete(Needed::Unknown))
887}
888
889/// Matches a byte string with escaped characters.
890///
891/// * The first argument matches the normal characters (it must not match the control character)
892/// * The second argument is the control character (like `\` in most languages)
893/// * The third argument matches the escaped characters and transforms them
894///
895/// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
896///
897/// ```
898/// # use nom8::{Err, error::ErrorKind, Needed, IResult};
899/// # use std::str::from_utf8;
900/// use nom8::bytes::streaming::{escaped_transform, tag};
901/// use nom8::character::streaming::alpha1;
902/// use nom8::branch::alt;
903/// use nom8::combinator::value;
904///
905/// fn parser(input: &str) -> IResult<&str, String> {
906///   escaped_transform(
907///     alpha1,
908///     '\\',
909///     alt((
910///       value("\\", tag("\\")),
911///       value("\"", tag("\"")),
912///       value("\n", tag("n")),
913///     ))
914///   )(input)
915/// }
916///
917/// assert_eq!(parser("ab\\\"cd\""), Ok(("\"", String::from("ab\"cd"))));
918/// ```
919#[cfg(feature = "alloc")]
920///
921/// **WARNING:** Deprecated, replaced with [`nom8::bytes::escaped_transform`][crate::bytes::escaped_transform] with input wrapped in [`nom8::input::Streaming`][crate::input::Streaming]
922#[deprecated(
923  since = "8.0.0",
924  note = "Replaced with `nom8::bytes::escaped_transform` with input wrapped in `nom8::input::Streaming`"
925)]
926pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
927  mut normal: F,
928  control_char: char,
929  mut transform: G,
930) -> impl FnMut(Input) -> IResult<Input, Output, Error>
931where
932  Input: Clone
933    + crate::input::Offset
934    + InputLength
935    + InputTake
936    + InputTakeAtPosition
937    + Slice<RangeFrom<usize>>
938    + InputIter,
939  Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
940  O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
941  O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
942  <Input as InputIter>::Item: crate::input::AsChar,
943  F: Parser<Input, O1, Error>,
944  G: Parser<Input, O2, Error>,
945  Error: ParseError<Input>,
946{
947  move |input: Input| escaped_transform_internal(input, &mut normal, control_char, &mut transform)
948}
949
950#[cfg(feature = "alloc")]
951pub(crate) fn escaped_transform_internal<Input, Error, F, G, O1, O2, ExtendItem, Output>(
952  input: Input,
953  normal: &mut F,
954  control_char: char,
955  transform: &mut G,
956) -> IResult<Input, Output, Error>
957where
958  Input: Clone
959    + crate::input::Offset
960    + InputLength
961    + InputTake
962    + InputTakeAtPosition
963    + Slice<RangeFrom<usize>>
964    + InputIter,
965  Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
966  O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
967  O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
968  <Input as InputIter>::Item: crate::input::AsChar,
969  F: Parser<Input, O1, Error>,
970  G: Parser<Input, O2, Error>,
971  Error: ParseError<Input>,
972{
973  use crate::input::AsChar;
974
975  let mut index = 0;
976  let mut res = input.new_builder();
977
978  let i = input.clone();
979
980  while index < i.input_len() {
981    let current_len = i.input_len();
982    let remainder = i.slice(index..);
983    match normal.parse(remainder.clone()) {
984      Ok((i2, o)) => {
985        o.extend_into(&mut res);
986        if i2.input_len() == 0 {
987          return Err(Err::Incomplete(Needed::Unknown));
988        } else if i2.input_len() == current_len {
989          return Ok((remainder, res));
990        } else {
991          index = input.offset(&i2);
992        }
993      }
994      Err(Err::Error(_)) => {
995        // unwrap() should be safe here since index < $i.input_len()
996        if remainder.iter_elements().next().unwrap().as_char() == control_char {
997          let next = index + control_char.len_utf8();
998          let input_len = input.input_len();
999
1000          if next >= input_len {
1001            return Err(Err::Incomplete(Needed::Unknown));
1002          } else {
1003            match transform.parse(i.slice(next..)) {
1004              Ok((i2, o)) => {
1005                o.extend_into(&mut res);
1006                if i2.input_len() == 0 {
1007                  return Err(Err::Incomplete(Needed::Unknown));
1008                } else {
1009                  index = input.offset(&i2);
1010                }
1011              }
1012              Err(e) => return Err(e),
1013            }
1014          }
1015        } else {
1016          return Ok((remainder, res));
1017        }
1018      }
1019      Err(e) => return Err(e),
1020    }
1021  }
1022  Err(Err::Incomplete(Needed::Unknown))
1023}
1024
1025#[cfg(test)]
1026mod tests {
1027  use crate::character::streaming::{
1028    alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
1029    multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
1030  };
1031  use crate::error::ErrorKind;
1032  use crate::input::AsChar;
1033  use crate::{Err, IResult, Needed};
1034
1035  #[test]
1036  fn is_a() {
1037    use crate::bytes::streaming::is_a;
1038
1039    fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
1040      is_a("ab")(i)
1041    }
1042
1043    let a = &b"abcd"[..];
1044    assert_eq!(a_or_b(a), Ok((&b"cd"[..], &b"ab"[..])));
1045
1046    let b = &b"bcde"[..];
1047    assert_eq!(a_or_b(b), Ok((&b"cde"[..], &b"b"[..])));
1048
1049    let c = &b"cdef"[..];
1050    assert_eq!(
1051      a_or_b(c),
1052      Err(Err::Error(error_position!(c, ErrorKind::IsA)))
1053    );
1054
1055    let d = &b"bacdef"[..];
1056    assert_eq!(a_or_b(d), Ok((&b"cdef"[..], &b"ba"[..])));
1057  }
1058
1059  #[test]
1060  fn is_not() {
1061    use crate::bytes::streaming::is_not;
1062
1063    fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
1064      is_not("ab")(i)
1065    }
1066
1067    let a = &b"cdab"[..];
1068    assert_eq!(a_or_b(a), Ok((&b"ab"[..], &b"cd"[..])));
1069
1070    let b = &b"cbde"[..];
1071    assert_eq!(a_or_b(b), Ok((&b"bde"[..], &b"c"[..])));
1072
1073    let c = &b"abab"[..];
1074    assert_eq!(
1075      a_or_b(c),
1076      Err(Err::Error(error_position!(c, ErrorKind::IsNot)))
1077    );
1078
1079    let d = &b"cdefba"[..];
1080    assert_eq!(a_or_b(d), Ok((&b"ba"[..], &b"cdef"[..])));
1081
1082    let e = &b"e"[..];
1083    assert_eq!(a_or_b(e), Err(Err::Incomplete(Needed::new(1))));
1084  }
1085
1086  #[test]
1087  fn take_until_incomplete() {
1088    use crate::bytes::streaming::take_until;
1089    fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
1090      take_until("end")(i)
1091    }
1092    assert_eq!(y(&b"nd"[..]), Err(Err::Incomplete(Needed::Unknown)));
1093    assert_eq!(y(&b"123"[..]), Err(Err::Incomplete(Needed::Unknown)));
1094    assert_eq!(y(&b"123en"[..]), Err(Err::Incomplete(Needed::Unknown)));
1095  }
1096
1097  #[test]
1098  fn take_until_incomplete_s() {
1099    use crate::bytes::streaming::take_until;
1100    fn ys(i: &str) -> IResult<&str, &str> {
1101      take_until("end")(i)
1102    }
1103    assert_eq!(ys("123en"), Err(Err::Incomplete(Needed::Unknown)));
1104  }
1105
1106  #[test]
1107  fn recognize() {
1108    use crate::bytes::streaming::{tag, take};
1109    use crate::combinator::recognize;
1110    use crate::sequence::delimited;
1111
1112    fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1113      recognize(delimited(tag("<!--"), take(5_usize), tag("-->")))(i)
1114    }
1115    let r = x(&b"<!-- abc --> aaa"[..]);
1116    assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
1117
1118    let semicolon = &b";"[..];
1119
1120    fn ya(i: &[u8]) -> IResult<&[u8], &[u8]> {
1121      recognize(alpha)(i)
1122    }
1123    let ra = ya(&b"abc;"[..]);
1124    assert_eq!(ra, Ok((semicolon, &b"abc"[..])));
1125
1126    fn yd(i: &[u8]) -> IResult<&[u8], &[u8]> {
1127      recognize(digit)(i)
1128    }
1129    let rd = yd(&b"123;"[..]);
1130    assert_eq!(rd, Ok((semicolon, &b"123"[..])));
1131
1132    fn yhd(i: &[u8]) -> IResult<&[u8], &[u8]> {
1133      recognize(hex_digit)(i)
1134    }
1135    let rhd = yhd(&b"123abcDEF;"[..]);
1136    assert_eq!(rhd, Ok((semicolon, &b"123abcDEF"[..])));
1137
1138    fn yod(i: &[u8]) -> IResult<&[u8], &[u8]> {
1139      recognize(oct_digit)(i)
1140    }
1141    let rod = yod(&b"1234567;"[..]);
1142    assert_eq!(rod, Ok((semicolon, &b"1234567"[..])));
1143
1144    fn yan(i: &[u8]) -> IResult<&[u8], &[u8]> {
1145      recognize(alphanumeric)(i)
1146    }
1147    let ran = yan(&b"123abc;"[..]);
1148    assert_eq!(ran, Ok((semicolon, &b"123abc"[..])));
1149
1150    fn ys(i: &[u8]) -> IResult<&[u8], &[u8]> {
1151      recognize(space)(i)
1152    }
1153    let rs = ys(&b" \t;"[..]);
1154    assert_eq!(rs, Ok((semicolon, &b" \t"[..])));
1155
1156    fn yms(i: &[u8]) -> IResult<&[u8], &[u8]> {
1157      recognize(multispace)(i)
1158    }
1159    let rms = yms(&b" \t\r\n;"[..]);
1160    assert_eq!(rms, Ok((semicolon, &b" \t\r\n"[..])));
1161  }
1162
1163  #[test]
1164  fn take_while() {
1165    use crate::bytes::streaming::take_while;
1166
1167    fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1168      take_while(AsChar::is_alpha)(i)
1169    }
1170    let a = b"";
1171    let b = b"abcd";
1172    let c = b"abcd123";
1173    let d = b"123";
1174
1175    assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1176    assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1177    assert_eq!(f(&c[..]), Ok((&d[..], &b[..])));
1178    assert_eq!(f(&d[..]), Ok((&d[..], &a[..])));
1179  }
1180
1181  #[test]
1182  fn take_while1() {
1183    use crate::bytes::streaming::take_while1;
1184
1185    fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1186      take_while1(AsChar::is_alpha)(i)
1187    }
1188    let a = b"";
1189    let b = b"abcd";
1190    let c = b"abcd123";
1191    let d = b"123";
1192
1193    assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1194    assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1195    assert_eq!(f(&c[..]), Ok((&b"123"[..], &b[..])));
1196    assert_eq!(
1197      f(&d[..]),
1198      Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
1199    );
1200  }
1201
1202  #[test]
1203  fn take_while_m_n() {
1204    use crate::bytes::streaming::take_while_m_n;
1205
1206    fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1207      take_while_m_n(2, 4, AsChar::is_alpha)(i)
1208    }
1209    let a = b"";
1210    let b = b"a";
1211    let c = b"abc";
1212    let d = b"abc123";
1213    let e = b"abcde";
1214    let f = b"123";
1215
1216    assert_eq!(x(&a[..]), Err(Err::Incomplete(Needed::new(2))));
1217    assert_eq!(x(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1218    assert_eq!(x(&c[..]), Err(Err::Incomplete(Needed::new(1))));
1219    assert_eq!(x(&d[..]), Ok((&b"123"[..], &c[..])));
1220    assert_eq!(x(&e[..]), Ok((&b"e"[..], &b"abcd"[..])));
1221    assert_eq!(
1222      x(&f[..]),
1223      Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN)))
1224    );
1225  }
1226
1227  #[test]
1228  fn take_till() {
1229    use crate::bytes::streaming::take_till;
1230
1231    fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1232      take_till(AsChar::is_alpha)(i)
1233    }
1234    let a = b"";
1235    let b = b"abcd";
1236    let c = b"123abcd";
1237    let d = b"123";
1238
1239    assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1240    assert_eq!(f(&b[..]), Ok((&b"abcd"[..], &b""[..])));
1241    assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
1242    assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
1243  }
1244
1245  #[test]
1246  fn take_till1() {
1247    use crate::bytes::streaming::take_till1;
1248
1249    fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1250      take_till1(AsChar::is_alpha)(i)
1251    }
1252    let a = b"";
1253    let b = b"abcd";
1254    let c = b"123abcd";
1255    let d = b"123";
1256
1257    assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1258    assert_eq!(
1259      f(&b[..]),
1260      Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1)))
1261    );
1262    assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
1263    assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
1264  }
1265
1266  #[test]
1267  fn take_while_utf8() {
1268    use crate::bytes::streaming::take_while;
1269
1270    fn f(i: &str) -> IResult<&str, &str> {
1271      take_while(|c| c != '點')(i)
1272    }
1273
1274    assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
1275    assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
1276    assert_eq!(f("abcd點"), Ok(("點", "abcd")));
1277    assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
1278
1279    fn g(i: &str) -> IResult<&str, &str> {
1280      take_while(|c| c == '點')(i)
1281    }
1282
1283    assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1284    assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1285    assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1286  }
1287
1288  #[test]
1289  fn take_till_utf8() {
1290    use crate::bytes::streaming::take_till;
1291
1292    fn f(i: &str) -> IResult<&str, &str> {
1293      take_till(|c| c == '點')(i)
1294    }
1295
1296    assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
1297    assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
1298    assert_eq!(f("abcd點"), Ok(("點", "abcd")));
1299    assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
1300
1301    fn g(i: &str) -> IResult<&str, &str> {
1302      take_till(|c| c != '點')(i)
1303    }
1304
1305    assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1306    assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1307    assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1308  }
1309
1310  #[test]
1311  fn take_utf8() {
1312    use crate::bytes::streaming::{take, take_while};
1313
1314    fn f(i: &str) -> IResult<&str, &str> {
1315      take(3_usize)(i)
1316    }
1317
1318    assert_eq!(f(""), Err(Err::Incomplete(Needed::Unknown)));
1319    assert_eq!(f("ab"), Err(Err::Incomplete(Needed::Unknown)));
1320    assert_eq!(f("點"), Err(Err::Incomplete(Needed::Unknown)));
1321    assert_eq!(f("ab點cd"), Ok(("cd", "ab點")));
1322    assert_eq!(f("a點bcd"), Ok(("cd", "a點b")));
1323    assert_eq!(f("a點b"), Ok(("", "a點b")));
1324
1325    fn g(i: &str) -> IResult<&str, &str> {
1326      take_while(|c| c == '點')(i)
1327    }
1328
1329    assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1330    assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1331    assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1332  }
1333
1334  #[test]
1335  fn take_while_m_n_utf8() {
1336    use crate::bytes::streaming::take_while_m_n;
1337
1338    fn parser(i: &str) -> IResult<&str, &str> {
1339      take_while_m_n(1, 1, |c| c == 'A' || c == '😃')(i)
1340    }
1341    assert_eq!(parser("A!"), Ok(("!", "A")));
1342    assert_eq!(parser("😃!"), Ok(("!", "😃")));
1343  }
1344
1345  #[test]
1346  fn take_while_m_n_utf8_full_match() {
1347    use crate::bytes::streaming::take_while_m_n;
1348
1349    fn parser(i: &str) -> IResult<&str, &str> {
1350      take_while_m_n(1, 1, |c: char| c.is_alphabetic())(i)
1351    }
1352    assert_eq!(parser("øn"), Ok(("n", "ø")));
1353  }
1354
1355  #[test]
1356  #[cfg(feature = "std")]
1357  fn recognize_take_while() {
1358    use crate::bytes::streaming::take_while;
1359    use crate::combinator::recognize;
1360
1361    fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1362      take_while(AsChar::is_alphanum)(i)
1363    }
1364    fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
1365      recognize(x)(i)
1366    }
1367    assert_eq!(x(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
1368    println!("X: {:?}", x(&b"ab"[..]));
1369    assert_eq!(y(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
1370  }
1371
1372  #[test]
1373  fn length_bytes() {
1374    use crate::input::Streaming;
1375    use crate::{bytes::streaming::tag, multi::length_data, number::streaming::le_u8};
1376
1377    fn x(i: Streaming<&[u8]>) -> IResult<Streaming<&[u8]>, &[u8]> {
1378      length_data(le_u8)(i)
1379    }
1380    assert_eq!(
1381      x(Streaming(b"\x02..>>")),
1382      Ok((Streaming(&b">>"[..]), &b".."[..]))
1383    );
1384    assert_eq!(
1385      x(Streaming(b"\x02..")),
1386      Ok((Streaming(&[][..]), &b".."[..]))
1387    );
1388    assert_eq!(x(Streaming(b"\x02.")), Err(Err::Incomplete(Needed::new(1))));
1389    assert_eq!(x(Streaming(b"\x02")), Err(Err::Incomplete(Needed::new(2))));
1390
1391    fn y(i: Streaming<&[u8]>) -> IResult<Streaming<&[u8]>, &[u8]> {
1392      let (i, _) = tag("magic")(i)?;
1393      length_data(le_u8)(i)
1394    }
1395    assert_eq!(
1396      y(Streaming(b"magic\x02..>>")),
1397      Ok((Streaming(&b">>"[..]), &b".."[..]))
1398    );
1399    assert_eq!(
1400      y(Streaming(b"magic\x02..")),
1401      Ok((Streaming(&[][..]), &b".."[..]))
1402    );
1403    assert_eq!(
1404      y(Streaming(b"magic\x02.")),
1405      Err(Err::Incomplete(Needed::new(1)))
1406    );
1407    assert_eq!(
1408      y(Streaming(b"magic\x02")),
1409      Err(Err::Incomplete(Needed::new(2)))
1410    );
1411  }
1412
1413  #[cfg(feature = "alloc")]
1414  #[test]
1415  fn case_insensitive() {
1416    use crate::bytes::streaming::tag_no_case;
1417
1418    fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
1419      tag_no_case("ABcd")(i)
1420    }
1421    assert_eq!(test(&b"aBCdefgh"[..]), Ok((&b"efgh"[..], &b"aBCd"[..])));
1422    assert_eq!(test(&b"abcdefgh"[..]), Ok((&b"efgh"[..], &b"abcd"[..])));
1423    assert_eq!(test(&b"ABCDefgh"[..]), Ok((&b"efgh"[..], &b"ABCD"[..])));
1424    assert_eq!(test(&b"ab"[..]), Err(Err::Incomplete(Needed::new(2))));
1425    assert_eq!(
1426      test(&b"Hello"[..]),
1427      Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag)))
1428    );
1429    assert_eq!(
1430      test(&b"Hel"[..]),
1431      Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag)))
1432    );
1433
1434    fn test2(i: &str) -> IResult<&str, &str> {
1435      tag_no_case("ABcd")(i)
1436    }
1437    assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
1438    assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
1439    assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
1440    assert_eq!(test2("ab"), Err(Err::Incomplete(Needed::new(2))));
1441    assert_eq!(
1442      test2("Hello"),
1443      Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag)))
1444    );
1445    assert_eq!(
1446      test2("Hel"),
1447      Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag)))
1448    );
1449  }
1450
1451  #[test]
1452  fn tag_fixed_size_array() {
1453    use crate::bytes::streaming::tag;
1454
1455    fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
1456      tag([0x42])(i)
1457    }
1458    fn test2(i: &[u8]) -> IResult<&[u8], &[u8]> {
1459      tag(&[0x42])(i)
1460    }
1461    let input = [0x42, 0x00];
1462    assert_eq!(test(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
1463    assert_eq!(test2(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
1464  }
1465}