16855e09eSopenharmony_ci//! Basic types to build the parsers
26855e09eSopenharmony_ci
36855e09eSopenharmony_ciuse self::Needed::*;
46855e09eSopenharmony_ciuse crate::error::{self, ErrorKind};
56855e09eSopenharmony_ciuse crate::lib::std::fmt;
66855e09eSopenharmony_ciuse core::num::NonZeroUsize;
76855e09eSopenharmony_ci
86855e09eSopenharmony_ci/// Holds the result of parsing functions
96855e09eSopenharmony_ci///
106855e09eSopenharmony_ci/// It depends on the input type `I`, the output type `O`, and the error type `E`
116855e09eSopenharmony_ci/// (by default `(I, nom::ErrorKind)`)
126855e09eSopenharmony_ci///
136855e09eSopenharmony_ci/// The `Ok` side is a pair containing the remainder of the input (the part of the data that
146855e09eSopenharmony_ci/// was not parsed) and the produced value. The `Err` side contains an instance of `nom::Err`.
156855e09eSopenharmony_ci///
166855e09eSopenharmony_ci/// Outside of the parsing code, you can use the [Finish::finish] method to convert
176855e09eSopenharmony_ci/// it to a more common result type
186855e09eSopenharmony_cipub type IResult<I, O, E = error::Error<I>> = Result<(I, O), Err<E>>;
196855e09eSopenharmony_ci
206855e09eSopenharmony_ci/// Helper trait to convert a parser's result to a more manageable type
216855e09eSopenharmony_cipub trait Finish<I, O, E> {
226855e09eSopenharmony_ci  /// converts the parser's result to a type that is more consumable by error
236855e09eSopenharmony_ci  /// management libraries. It keeps the same `Ok` branch, and merges `Err::Error`
246855e09eSopenharmony_ci  /// and `Err::Failure` into the `Err` side.
256855e09eSopenharmony_ci  ///
266855e09eSopenharmony_ci  /// *warning*: if the result is `Err(Err::Incomplete(_))`, this method will panic.
276855e09eSopenharmony_ci  /// - "complete" parsers: It will not be an issue, `Incomplete` is never used
286855e09eSopenharmony_ci  /// - "streaming" parsers: `Incomplete` will be returned if there's not enough data
296855e09eSopenharmony_ci  /// for the parser to decide, and you should gather more data before parsing again.
306855e09eSopenharmony_ci  /// Once the parser returns either `Ok(_)`, `Err(Err::Error(_))` or `Err(Err::Failure(_))`,
316855e09eSopenharmony_ci  /// you can get out of the parsing loop and call `finish()` on the parser's result
326855e09eSopenharmony_ci  fn finish(self) -> Result<(I, O), E>;
336855e09eSopenharmony_ci}
346855e09eSopenharmony_ci
356855e09eSopenharmony_ciimpl<I, O, E> Finish<I, O, E> for IResult<I, O, E> {
366855e09eSopenharmony_ci  fn finish(self) -> Result<(I, O), E> {
376855e09eSopenharmony_ci    match self {
386855e09eSopenharmony_ci      Ok(res) => Ok(res),
396855e09eSopenharmony_ci      Err(Err::Error(e)) | Err(Err::Failure(e)) => Err(e),
406855e09eSopenharmony_ci      Err(Err::Incomplete(_)) => {
416855e09eSopenharmony_ci        panic!("Cannot call `finish()` on `Err(Err::Incomplete(_))`: this result means that the parser does not have enough data to decide, you should gather more data and try to reapply  the parser instead")
426855e09eSopenharmony_ci      }
436855e09eSopenharmony_ci    }
446855e09eSopenharmony_ci  }
456855e09eSopenharmony_ci}
466855e09eSopenharmony_ci
476855e09eSopenharmony_ci/// Contains information on needed data if a parser returned `Incomplete`
486855e09eSopenharmony_ci#[derive(Debug, PartialEq, Eq, Clone, Copy)]
496855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
506855e09eSopenharmony_cipub enum Needed {
516855e09eSopenharmony_ci  /// Needs more data, but we do not know how much
526855e09eSopenharmony_ci  Unknown,
536855e09eSopenharmony_ci  /// Contains the required data size in bytes
546855e09eSopenharmony_ci  Size(NonZeroUsize),
556855e09eSopenharmony_ci}
566855e09eSopenharmony_ci
576855e09eSopenharmony_ciimpl Needed {
586855e09eSopenharmony_ci  /// Creates `Needed` instance, returns `Needed::Unknown` if the argument is zero
596855e09eSopenharmony_ci  pub fn new(s: usize) -> Self {
606855e09eSopenharmony_ci    match NonZeroUsize::new(s) {
616855e09eSopenharmony_ci      Some(sz) => Needed::Size(sz),
626855e09eSopenharmony_ci      None => Needed::Unknown,
636855e09eSopenharmony_ci    }
646855e09eSopenharmony_ci  }
656855e09eSopenharmony_ci
666855e09eSopenharmony_ci  /// Indicates if we know how many bytes we need
676855e09eSopenharmony_ci  pub fn is_known(&self) -> bool {
686855e09eSopenharmony_ci    *self != Unknown
696855e09eSopenharmony_ci  }
706855e09eSopenharmony_ci
716855e09eSopenharmony_ci  /// Maps a `Needed` to `Needed` by applying a function to a contained `Size` value.
726855e09eSopenharmony_ci  #[inline]
736855e09eSopenharmony_ci  pub fn map<F: Fn(NonZeroUsize) -> usize>(self, f: F) -> Needed {
746855e09eSopenharmony_ci    match self {
756855e09eSopenharmony_ci      Unknown => Unknown,
766855e09eSopenharmony_ci      Size(n) => Needed::new(f(n)),
776855e09eSopenharmony_ci    }
786855e09eSopenharmony_ci  }
796855e09eSopenharmony_ci}
806855e09eSopenharmony_ci
816855e09eSopenharmony_ci/// The `Err` enum indicates the parser was not successful
826855e09eSopenharmony_ci///
836855e09eSopenharmony_ci/// It has three cases:
846855e09eSopenharmony_ci///
856855e09eSopenharmony_ci/// * `Incomplete` indicates that more data is needed to decide. The `Needed` enum
866855e09eSopenharmony_ci/// can contain how many additional bytes are necessary. If you are sure your parser
876855e09eSopenharmony_ci/// is working on full data, you can wrap your parser with the `complete` combinator
886855e09eSopenharmony_ci/// to transform that case in `Error`
896855e09eSopenharmony_ci/// * `Error` means some parser did not succeed, but another one might (as an example,
906855e09eSopenharmony_ci/// when testing different branches of an `alt` combinator)
916855e09eSopenharmony_ci/// * `Failure` indicates an unrecoverable error. As an example, if you recognize a prefix
926855e09eSopenharmony_ci/// to decide on the next parser to apply, and that parser fails, you know there's no need
936855e09eSopenharmony_ci/// to try other parsers, you were already in the right branch, so the data is invalid
946855e09eSopenharmony_ci///
956855e09eSopenharmony_ci#[derive(Debug, Clone, PartialEq)]
966855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
976855e09eSopenharmony_cipub enum Err<E> {
986855e09eSopenharmony_ci  /// There was not enough data
996855e09eSopenharmony_ci  Incomplete(Needed),
1006855e09eSopenharmony_ci  /// The parser had an error (recoverable)
1016855e09eSopenharmony_ci  Error(E),
1026855e09eSopenharmony_ci  /// The parser had an unrecoverable error: we got to the right
1036855e09eSopenharmony_ci  /// branch and we know other branches won't work, so backtrack
1046855e09eSopenharmony_ci  /// as fast as possible
1056855e09eSopenharmony_ci  Failure(E),
1066855e09eSopenharmony_ci}
1076855e09eSopenharmony_ci
1086855e09eSopenharmony_ciimpl<E> Err<E> {
1096855e09eSopenharmony_ci  /// Tests if the result is Incomplete
1106855e09eSopenharmony_ci  pub fn is_incomplete(&self) -> bool {
1116855e09eSopenharmony_ci    if let Err::Incomplete(_) = self {
1126855e09eSopenharmony_ci      true
1136855e09eSopenharmony_ci    } else {
1146855e09eSopenharmony_ci      false
1156855e09eSopenharmony_ci    }
1166855e09eSopenharmony_ci  }
1176855e09eSopenharmony_ci
1186855e09eSopenharmony_ci  /// Applies the given function to the inner error
1196855e09eSopenharmony_ci  pub fn map<E2, F>(self, f: F) -> Err<E2>
1206855e09eSopenharmony_ci  where
1216855e09eSopenharmony_ci    F: FnOnce(E) -> E2,
1226855e09eSopenharmony_ci  {
1236855e09eSopenharmony_ci    match self {
1246855e09eSopenharmony_ci      Err::Incomplete(n) => Err::Incomplete(n),
1256855e09eSopenharmony_ci      Err::Failure(t) => Err::Failure(f(t)),
1266855e09eSopenharmony_ci      Err::Error(t) => Err::Error(f(t)),
1276855e09eSopenharmony_ci    }
1286855e09eSopenharmony_ci  }
1296855e09eSopenharmony_ci
1306855e09eSopenharmony_ci  /// Automatically converts between errors if the underlying type supports it
1316855e09eSopenharmony_ci  pub fn convert<F>(e: Err<F>) -> Self
1326855e09eSopenharmony_ci  where
1336855e09eSopenharmony_ci    E: From<F>,
1346855e09eSopenharmony_ci  {
1356855e09eSopenharmony_ci    e.map(crate::lib::std::convert::Into::into)
1366855e09eSopenharmony_ci  }
1376855e09eSopenharmony_ci}
1386855e09eSopenharmony_ci
1396855e09eSopenharmony_ciimpl<T> Err<(T, ErrorKind)> {
1406855e09eSopenharmony_ci  /// Maps `Err<(T, ErrorKind)>` to `Err<(U, ErrorKind)>` with the given `F: T -> U`
1416855e09eSopenharmony_ci  pub fn map_input<U, F>(self, f: F) -> Err<(U, ErrorKind)>
1426855e09eSopenharmony_ci  where
1436855e09eSopenharmony_ci    F: FnOnce(T) -> U,
1446855e09eSopenharmony_ci  {
1456855e09eSopenharmony_ci    match self {
1466855e09eSopenharmony_ci      Err::Incomplete(n) => Err::Incomplete(n),
1476855e09eSopenharmony_ci      Err::Failure((input, k)) => Err::Failure((f(input), k)),
1486855e09eSopenharmony_ci      Err::Error((input, k)) => Err::Error((f(input), k)),
1496855e09eSopenharmony_ci    }
1506855e09eSopenharmony_ci  }
1516855e09eSopenharmony_ci}
1526855e09eSopenharmony_ci
1536855e09eSopenharmony_ciimpl<T> Err<error::Error<T>> {
1546855e09eSopenharmony_ci  /// Maps `Err<error::Error<T>>` to `Err<error::Error<U>>` with the given `F: T -> U`
1556855e09eSopenharmony_ci  pub fn map_input<U, F>(self, f: F) -> Err<error::Error<U>>
1566855e09eSopenharmony_ci  where
1576855e09eSopenharmony_ci    F: FnOnce(T) -> U,
1586855e09eSopenharmony_ci  {
1596855e09eSopenharmony_ci    match self {
1606855e09eSopenharmony_ci      Err::Incomplete(n) => Err::Incomplete(n),
1616855e09eSopenharmony_ci      Err::Failure(error::Error { input, code }) => Err::Failure(error::Error {
1626855e09eSopenharmony_ci        input: f(input),
1636855e09eSopenharmony_ci        code,
1646855e09eSopenharmony_ci      }),
1656855e09eSopenharmony_ci      Err::Error(error::Error { input, code }) => Err::Error(error::Error {
1666855e09eSopenharmony_ci        input: f(input),
1676855e09eSopenharmony_ci        code,
1686855e09eSopenharmony_ci      }),
1696855e09eSopenharmony_ci    }
1706855e09eSopenharmony_ci  }
1716855e09eSopenharmony_ci}
1726855e09eSopenharmony_ci
1736855e09eSopenharmony_ci#[cfg(feature = "alloc")]
1746855e09eSopenharmony_ciuse crate::lib::std::{borrow::ToOwned, string::String, vec::Vec};
1756855e09eSopenharmony_ci#[cfg(feature = "alloc")]
1766855e09eSopenharmony_ciimpl Err<(&[u8], ErrorKind)> {
1776855e09eSopenharmony_ci  /// Obtaining ownership
1786855e09eSopenharmony_ci  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
1796855e09eSopenharmony_ci  pub fn to_owned(self) -> Err<(Vec<u8>, ErrorKind)> {
1806855e09eSopenharmony_ci    self.map_input(ToOwned::to_owned)
1816855e09eSopenharmony_ci  }
1826855e09eSopenharmony_ci}
1836855e09eSopenharmony_ci
1846855e09eSopenharmony_ci#[cfg(feature = "alloc")]
1856855e09eSopenharmony_ciimpl Err<(&str, ErrorKind)> {
1866855e09eSopenharmony_ci  /// Obtaining ownership
1876855e09eSopenharmony_ci  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
1886855e09eSopenharmony_ci  pub fn to_owned(self) -> Err<(String, ErrorKind)> {
1896855e09eSopenharmony_ci    self.map_input(ToOwned::to_owned)
1906855e09eSopenharmony_ci  }
1916855e09eSopenharmony_ci}
1926855e09eSopenharmony_ci
1936855e09eSopenharmony_ci#[cfg(feature = "alloc")]
1946855e09eSopenharmony_ciimpl Err<error::Error<&[u8]>> {
1956855e09eSopenharmony_ci  /// Obtaining ownership
1966855e09eSopenharmony_ci  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
1976855e09eSopenharmony_ci  pub fn to_owned(self) -> Err<error::Error<Vec<u8>>> {
1986855e09eSopenharmony_ci    self.map_input(ToOwned::to_owned)
1996855e09eSopenharmony_ci  }
2006855e09eSopenharmony_ci}
2016855e09eSopenharmony_ci
2026855e09eSopenharmony_ci#[cfg(feature = "alloc")]
2036855e09eSopenharmony_ciimpl Err<error::Error<&str>> {
2046855e09eSopenharmony_ci  /// Obtaining ownership
2056855e09eSopenharmony_ci  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
2066855e09eSopenharmony_ci  pub fn to_owned(self) -> Err<error::Error<String>> {
2076855e09eSopenharmony_ci    self.map_input(ToOwned::to_owned)
2086855e09eSopenharmony_ci  }
2096855e09eSopenharmony_ci}
2106855e09eSopenharmony_ci
2116855e09eSopenharmony_ciimpl<E: Eq> Eq for Err<E> {}
2126855e09eSopenharmony_ci
2136855e09eSopenharmony_ciimpl<E> fmt::Display for Err<E>
2146855e09eSopenharmony_ciwhere
2156855e09eSopenharmony_ci  E: fmt::Debug,
2166855e09eSopenharmony_ci{
2176855e09eSopenharmony_ci  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2186855e09eSopenharmony_ci    match self {
2196855e09eSopenharmony_ci      Err::Incomplete(Needed::Size(u)) => write!(f, "Parsing requires {} bytes/chars", u),
2206855e09eSopenharmony_ci      Err::Incomplete(Needed::Unknown) => write!(f, "Parsing requires more data"),
2216855e09eSopenharmony_ci      Err::Failure(c) => write!(f, "Parsing Failure: {:?}", c),
2226855e09eSopenharmony_ci      Err::Error(c) => write!(f, "Parsing Error: {:?}", c),
2236855e09eSopenharmony_ci    }
2246855e09eSopenharmony_ci  }
2256855e09eSopenharmony_ci}
2266855e09eSopenharmony_ci
2276855e09eSopenharmony_ci#[cfg(feature = "std")]
2286855e09eSopenharmony_ciuse std::error::Error;
2296855e09eSopenharmony_ci
2306855e09eSopenharmony_ci#[cfg(feature = "std")]
2316855e09eSopenharmony_ciimpl<E> Error for Err<E>
2326855e09eSopenharmony_ciwhere
2336855e09eSopenharmony_ci  E: fmt::Debug,
2346855e09eSopenharmony_ci{
2356855e09eSopenharmony_ci  fn source(&self) -> Option<&(dyn Error + 'static)> {
2366855e09eSopenharmony_ci    None // no underlying error
2376855e09eSopenharmony_ci  }
2386855e09eSopenharmony_ci}
2396855e09eSopenharmony_ci
2406855e09eSopenharmony_ci/// All nom parsers implement this trait
2416855e09eSopenharmony_cipub trait Parser<I, O, E> {
2426855e09eSopenharmony_ci  /// A parser takes in input type, and returns a `Result` containing
2436855e09eSopenharmony_ci  /// either the remaining input and the output value, or an error
2446855e09eSopenharmony_ci  fn parse(&mut self, input: I) -> IResult<I, O, E>;
2456855e09eSopenharmony_ci
2466855e09eSopenharmony_ci  /// Maps a function over the result of a parser
2476855e09eSopenharmony_ci  fn map<G, O2>(self, g: G) -> Map<Self, G, O>
2486855e09eSopenharmony_ci  where
2496855e09eSopenharmony_ci    G: Fn(O) -> O2,
2506855e09eSopenharmony_ci    Self: core::marker::Sized,
2516855e09eSopenharmony_ci  {
2526855e09eSopenharmony_ci    Map {
2536855e09eSopenharmony_ci      f: self,
2546855e09eSopenharmony_ci      g,
2556855e09eSopenharmony_ci      phantom: core::marker::PhantomData,
2566855e09eSopenharmony_ci    }
2576855e09eSopenharmony_ci  }
2586855e09eSopenharmony_ci
2596855e09eSopenharmony_ci  /// Creates a second parser from the output of the first one, then apply over the rest of the input
2606855e09eSopenharmony_ci  fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O>
2616855e09eSopenharmony_ci  where
2626855e09eSopenharmony_ci    G: FnMut(O) -> H,
2636855e09eSopenharmony_ci    H: Parser<I, O2, E>,
2646855e09eSopenharmony_ci    Self: core::marker::Sized,
2656855e09eSopenharmony_ci  {
2666855e09eSopenharmony_ci    FlatMap {
2676855e09eSopenharmony_ci      f: self,
2686855e09eSopenharmony_ci      g,
2696855e09eSopenharmony_ci      phantom: core::marker::PhantomData,
2706855e09eSopenharmony_ci    }
2716855e09eSopenharmony_ci  }
2726855e09eSopenharmony_ci
2736855e09eSopenharmony_ci  /// Applies a second parser over the output of the first one
2746855e09eSopenharmony_ci  fn and_then<G, O2>(self, g: G) -> AndThen<Self, G, O>
2756855e09eSopenharmony_ci  where
2766855e09eSopenharmony_ci    G: Parser<O, O2, E>,
2776855e09eSopenharmony_ci    Self: core::marker::Sized,
2786855e09eSopenharmony_ci  {
2796855e09eSopenharmony_ci    AndThen {
2806855e09eSopenharmony_ci      f: self,
2816855e09eSopenharmony_ci      g,
2826855e09eSopenharmony_ci      phantom: core::marker::PhantomData,
2836855e09eSopenharmony_ci    }
2846855e09eSopenharmony_ci  }
2856855e09eSopenharmony_ci
2866855e09eSopenharmony_ci  /// Applies a second parser after the first one, return their results as a tuple
2876855e09eSopenharmony_ci  fn and<G, O2>(self, g: G) -> And<Self, G>
2886855e09eSopenharmony_ci  where
2896855e09eSopenharmony_ci    G: Parser<I, O2, E>,
2906855e09eSopenharmony_ci    Self: core::marker::Sized,
2916855e09eSopenharmony_ci  {
2926855e09eSopenharmony_ci    And { f: self, g }
2936855e09eSopenharmony_ci  }
2946855e09eSopenharmony_ci
2956855e09eSopenharmony_ci  /// Applies a second parser over the input if the first one failed
2966855e09eSopenharmony_ci  fn or<G>(self, g: G) -> Or<Self, G>
2976855e09eSopenharmony_ci  where
2986855e09eSopenharmony_ci    G: Parser<I, O, E>,
2996855e09eSopenharmony_ci    Self: core::marker::Sized,
3006855e09eSopenharmony_ci  {
3016855e09eSopenharmony_ci    Or { f: self, g }
3026855e09eSopenharmony_ci  }
3036855e09eSopenharmony_ci
3046855e09eSopenharmony_ci  /// automatically converts the parser's output and error values to another type, as long as they
3056855e09eSopenharmony_ci  /// implement the `From` trait
3066855e09eSopenharmony_ci  fn into<O2: From<O>, E2: From<E>>(self) -> Into<Self, O, O2, E, E2>
3076855e09eSopenharmony_ci  where
3086855e09eSopenharmony_ci    Self: core::marker::Sized,
3096855e09eSopenharmony_ci  {
3106855e09eSopenharmony_ci    Into {
3116855e09eSopenharmony_ci      f: self,
3126855e09eSopenharmony_ci      phantom_out1: core::marker::PhantomData,
3136855e09eSopenharmony_ci      phantom_err1: core::marker::PhantomData,
3146855e09eSopenharmony_ci      phantom_out2: core::marker::PhantomData,
3156855e09eSopenharmony_ci      phantom_err2: core::marker::PhantomData,
3166855e09eSopenharmony_ci    }
3176855e09eSopenharmony_ci  }
3186855e09eSopenharmony_ci}
3196855e09eSopenharmony_ci
3206855e09eSopenharmony_ciimpl<'a, I, O, E, F> Parser<I, O, E> for F
3216855e09eSopenharmony_ciwhere
3226855e09eSopenharmony_ci  F: FnMut(I) -> IResult<I, O, E> + 'a,
3236855e09eSopenharmony_ci{
3246855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O, E> {
3256855e09eSopenharmony_ci    self(i)
3266855e09eSopenharmony_ci  }
3276855e09eSopenharmony_ci}
3286855e09eSopenharmony_ci
3296855e09eSopenharmony_ci#[cfg(feature = "alloc")]
3306855e09eSopenharmony_ciuse alloc::boxed::Box;
3316855e09eSopenharmony_ci
3326855e09eSopenharmony_ci#[cfg(feature = "alloc")]
3336855e09eSopenharmony_ciimpl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> {
3346855e09eSopenharmony_ci  fn parse(&mut self, input: I) -> IResult<I, O, E> {
3356855e09eSopenharmony_ci    (**self).parse(input)
3366855e09eSopenharmony_ci  }
3376855e09eSopenharmony_ci}
3386855e09eSopenharmony_ci
3396855e09eSopenharmony_ci/// Implementation of `Parser::map`
3406855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
3416855e09eSopenharmony_cipub struct Map<F, G, O1> {
3426855e09eSopenharmony_ci  f: F,
3436855e09eSopenharmony_ci  g: G,
3446855e09eSopenharmony_ci  phantom: core::marker::PhantomData<O1>,
3456855e09eSopenharmony_ci}
3466855e09eSopenharmony_ci
3476855e09eSopenharmony_ciimpl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> O2> Parser<I, O2, E> for Map<F, G, O1> {
3486855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O2, E> {
3496855e09eSopenharmony_ci    match self.f.parse(i) {
3506855e09eSopenharmony_ci      Err(e) => Err(e),
3516855e09eSopenharmony_ci      Ok((i, o)) => Ok((i, (self.g)(o))),
3526855e09eSopenharmony_ci    }
3536855e09eSopenharmony_ci  }
3546855e09eSopenharmony_ci}
3556855e09eSopenharmony_ci
3566855e09eSopenharmony_ci/// Implementation of `Parser::flat_map`
3576855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
3586855e09eSopenharmony_cipub struct FlatMap<F, G, O1> {
3596855e09eSopenharmony_ci  f: F,
3606855e09eSopenharmony_ci  g: G,
3616855e09eSopenharmony_ci  phantom: core::marker::PhantomData<O1>,
3626855e09eSopenharmony_ci}
3636855e09eSopenharmony_ci
3646855e09eSopenharmony_ciimpl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> H, H: Parser<I, O2, E>> Parser<I, O2, E>
3656855e09eSopenharmony_ci  for FlatMap<F, G, O1>
3666855e09eSopenharmony_ci{
3676855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O2, E> {
3686855e09eSopenharmony_ci    let (i, o1) = self.f.parse(i)?;
3696855e09eSopenharmony_ci    (self.g)(o1).parse(i)
3706855e09eSopenharmony_ci  }
3716855e09eSopenharmony_ci}
3726855e09eSopenharmony_ci
3736855e09eSopenharmony_ci/// Implementation of `Parser::and_then`
3746855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
3756855e09eSopenharmony_cipub struct AndThen<F, G, O1> {
3766855e09eSopenharmony_ci  f: F,
3776855e09eSopenharmony_ci  g: G,
3786855e09eSopenharmony_ci  phantom: core::marker::PhantomData<O1>,
3796855e09eSopenharmony_ci}
3806855e09eSopenharmony_ci
3816855e09eSopenharmony_ciimpl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Parser<O1, O2, E>> Parser<I, O2, E>
3826855e09eSopenharmony_ci  for AndThen<F, G, O1>
3836855e09eSopenharmony_ci{
3846855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O2, E> {
3856855e09eSopenharmony_ci    let (i, o1) = self.f.parse(i)?;
3866855e09eSopenharmony_ci    let (_, o2) = self.g.parse(o1)?;
3876855e09eSopenharmony_ci    Ok((i, o2))
3886855e09eSopenharmony_ci  }
3896855e09eSopenharmony_ci}
3906855e09eSopenharmony_ci
3916855e09eSopenharmony_ci/// Implementation of `Parser::and`
3926855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
3936855e09eSopenharmony_cipub struct And<F, G> {
3946855e09eSopenharmony_ci  f: F,
3956855e09eSopenharmony_ci  g: G,
3966855e09eSopenharmony_ci}
3976855e09eSopenharmony_ci
3986855e09eSopenharmony_ciimpl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Parser<I, O2, E>> Parser<I, (O1, O2), E>
3996855e09eSopenharmony_ci  for And<F, G>
4006855e09eSopenharmony_ci{
4016855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, (O1, O2), E> {
4026855e09eSopenharmony_ci    let (i, o1) = self.f.parse(i)?;
4036855e09eSopenharmony_ci    let (i, o2) = self.g.parse(i)?;
4046855e09eSopenharmony_ci    Ok((i, (o1, o2)))
4056855e09eSopenharmony_ci  }
4066855e09eSopenharmony_ci}
4076855e09eSopenharmony_ci
4086855e09eSopenharmony_ci/// Implementation of `Parser::or`
4096855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
4106855e09eSopenharmony_cipub struct Or<F, G> {
4116855e09eSopenharmony_ci  f: F,
4126855e09eSopenharmony_ci  g: G,
4136855e09eSopenharmony_ci}
4146855e09eSopenharmony_ci
4156855e09eSopenharmony_ciimpl<'a, I: Clone, O, E: crate::error::ParseError<I>, F: Parser<I, O, E>, G: Parser<I, O, E>>
4166855e09eSopenharmony_ci  Parser<I, O, E> for Or<F, G>
4176855e09eSopenharmony_ci{
4186855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O, E> {
4196855e09eSopenharmony_ci    match self.f.parse(i.clone()) {
4206855e09eSopenharmony_ci      Err(Err::Error(e1)) => match self.g.parse(i) {
4216855e09eSopenharmony_ci        Err(Err::Error(e2)) => Err(Err::Error(e1.or(e2))),
4226855e09eSopenharmony_ci        res => res,
4236855e09eSopenharmony_ci      },
4246855e09eSopenharmony_ci      res => res,
4256855e09eSopenharmony_ci    }
4266855e09eSopenharmony_ci  }
4276855e09eSopenharmony_ci}
4286855e09eSopenharmony_ci
4296855e09eSopenharmony_ci/// Implementation of `Parser::into`
4306855e09eSopenharmony_ci#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
4316855e09eSopenharmony_cipub struct Into<F, O1, O2: From<O1>, E1, E2: From<E1>> {
4326855e09eSopenharmony_ci  f: F,
4336855e09eSopenharmony_ci  phantom_out1: core::marker::PhantomData<O1>,
4346855e09eSopenharmony_ci  phantom_err1: core::marker::PhantomData<E1>,
4356855e09eSopenharmony_ci  phantom_out2: core::marker::PhantomData<O2>,
4366855e09eSopenharmony_ci  phantom_err2: core::marker::PhantomData<E2>,
4376855e09eSopenharmony_ci}
4386855e09eSopenharmony_ci
4396855e09eSopenharmony_ciimpl<
4406855e09eSopenharmony_ci    'a,
4416855e09eSopenharmony_ci    I: Clone,
4426855e09eSopenharmony_ci    O1,
4436855e09eSopenharmony_ci    O2: From<O1>,
4446855e09eSopenharmony_ci    E1,
4456855e09eSopenharmony_ci    E2: crate::error::ParseError<I> + From<E1>,
4466855e09eSopenharmony_ci    F: Parser<I, O1, E1>,
4476855e09eSopenharmony_ci  > Parser<I, O2, E2> for Into<F, O1, O2, E1, E2>
4486855e09eSopenharmony_ci{
4496855e09eSopenharmony_ci  fn parse(&mut self, i: I) -> IResult<I, O2, E2> {
4506855e09eSopenharmony_ci    match self.f.parse(i) {
4516855e09eSopenharmony_ci      Ok((i, o)) => Ok((i, o.into())),
4526855e09eSopenharmony_ci      Err(Err::Error(e)) => Err(Err::Error(e.into())),
4536855e09eSopenharmony_ci      Err(Err::Failure(e)) => Err(Err::Failure(e.into())),
4546855e09eSopenharmony_ci      Err(Err::Incomplete(e)) => Err(Err::Incomplete(e)),
4556855e09eSopenharmony_ci    }
4566855e09eSopenharmony_ci  }
4576855e09eSopenharmony_ci}
4586855e09eSopenharmony_ci
4596855e09eSopenharmony_ci#[cfg(test)]
4606855e09eSopenharmony_cimod tests {
4616855e09eSopenharmony_ci  use super::*;
4626855e09eSopenharmony_ci  use crate::error::ErrorKind;
4636855e09eSopenharmony_ci
4646855e09eSopenharmony_ci  #[doc(hidden)]
4656855e09eSopenharmony_ci  #[macro_export]
4666855e09eSopenharmony_ci  macro_rules! assert_size (
4676855e09eSopenharmony_ci    ($t:ty, $sz:expr) => (
4686855e09eSopenharmony_ci      assert_eq!(crate::lib::std::mem::size_of::<$t>(), $sz);
4696855e09eSopenharmony_ci    );
4706855e09eSopenharmony_ci  );
4716855e09eSopenharmony_ci
4726855e09eSopenharmony_ci  #[test]
4736855e09eSopenharmony_ci  #[cfg(target_pointer_width = "64")]
4746855e09eSopenharmony_ci  fn size_test() {
4756855e09eSopenharmony_ci    assert_size!(IResult<&[u8], &[u8], (&[u8], u32)>, 40);
4766855e09eSopenharmony_ci    //FIXME: since rust 1.65, this is now 32 bytes, likely thanks to https://github.com/rust-lang/rust/pull/94075
4776855e09eSopenharmony_ci    // deactivating that test for now because it'll have different values depending on the rust version
4786855e09eSopenharmony_ci    // assert_size!(IResult<&str, &str, u32>, 40);
4796855e09eSopenharmony_ci    assert_size!(Needed, 8);
4806855e09eSopenharmony_ci    assert_size!(Err<u32>, 16);
4816855e09eSopenharmony_ci    assert_size!(ErrorKind, 1);
4826855e09eSopenharmony_ci  }
4836855e09eSopenharmony_ci
4846855e09eSopenharmony_ci  #[test]
4856855e09eSopenharmony_ci  fn err_map_test() {
4866855e09eSopenharmony_ci    let e = Err::Error(1);
4876855e09eSopenharmony_ci    assert_eq!(e.map(|v| v + 1), Err::Error(2));
4886855e09eSopenharmony_ci  }
4896855e09eSopenharmony_ci}
490