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