useself::Needed::*; usecrate::error::{self, ErrorKind}; usecrate::lib::std::fmt; use core::num::NonZeroUsize;
/// Holds the result of parsing functions /// /// It depends on the input type `I`, the output type `O`, and the error type `E` /// (by default `(I, nom::ErrorKind)`) /// /// The `Ok` side is a pair containing the remainder of the input (the part of the data that /// was not parsed) and the produced value. The `Err` side contains an instance of `nom::Err`. /// /// Outside of the parsing code, you can use the [Finish::finish] method to convert /// it to a more common result type pubtype IResult<I, O, E = error::Error<I>> = Result<(I, O), Err<E>>;
/// Helper trait to convert a parser's result to a more manageable type pubtrait Finish<I, O, E> { /// converts the parser's result to a type that is more consumable by error /// management libraries. It keeps the same `Ok` branch, and merges `Err::Error` /// and `Err::Failure` into the `Err` side. /// /// *warning*: if the result is `Err(Err::Incomplete(_))`, this method will panic. /// - "complete" parsers: It will not be an issue, `Incomplete` is never used /// - "streaming" parsers: `Incomplete` will be returned if there's not enough data /// for the parser to decide, and you should gather more data before parsing again. /// Once the parser returns either `Ok(_)`, `Err(Err::Error(_))` or `Err(Err::Failure(_))`, /// you can get out of the parsing loop and call `finish()` on the parser's result fn finish(self) -> Result<(I, O), E>;
}
impl<I, O, E> Finish<I, O, E> for IResult<I, O, E> { fn finish(self) -> Result<(I, O), E> { matchself {
Ok(res) => Ok(res),
Err(Err::Error(e)) | Err(Err::Failure(e)) => Err(e),
Err(Err::Incomplete(_)) => {
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")
}
}
}
}
/// Contains information on needed data if a parser returned `Incomplete` #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pubenum Needed { /// Needs more data, but we do not know how much
Unknown, /// Contains the required data size in bytes
Size(NonZeroUsize),
}
impl Needed { /// Creates `Needed` instance, returns `Needed::Unknown` if the argument is zero pubfn new(s: usize) -> Self { match NonZeroUsize::new(s) {
Some(sz) => Needed::Size(sz),
None => Needed::Unknown,
}
}
/// Indicates if we know how many bytes we need pubfn is_known(&self) -> bool {
*self != Unknown
}
/// Maps a `Needed` to `Needed` by applying a function to a contained `Size` value. #[inline] pubfn map<F: Fn(NonZeroUsize) -> usize>(self, f: F) -> Needed { matchself {
Unknown => Unknown,
Size(n) => Needed::new(f(n)),
}
}
}
/// The `Err` enum indicates the parser was not successful /// /// It has three cases: /// /// * `Incomplete` indicates that more data is needed to decide. The `Needed` enum /// can contain how many additional bytes are necessary. If you are sure your parser /// is working on full data, you can wrap your parser with the `complete` combinator /// to transform that case in `Error` /// * `Error` means some parser did not succeed, but another one might (as an example, /// when testing different branches of an `alt` combinator) /// * `Failure` indicates an unrecoverable error. As an example, if you recognize a prefix /// to decide on the next parser to apply, and that parser fails, you know there's no need /// to try other parsers, you were already in the right branch, so the data is invalid /// #[derive(Debug, Clone, PartialEq)] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pubenum Err<E> { /// There was not enough data
Incomplete(Needed), /// The parser had an error (recoverable)
Error(E), /// The parser had an unrecoverable error: we got to the right /// branch and we know other branches won't work, so backtrack /// as fast as possible
Failure(E),
}
impl<E> Err<E> { /// Tests if the result is Incomplete pubfn is_incomplete(&self) -> bool { iflet Err::Incomplete(_) = self { true
} else { false
}
}
/// Applies the given function to the inner error pubfn map<E2, F>(self, f: F) -> Err<E2> where
F: FnOnce(E) -> E2,
{ matchself {
Err::Incomplete(n) => Err::Incomplete(n),
Err::Failure(t) => Err::Failure(f(t)),
Err::Error(t) => Err::Error(f(t)),
}
}
/// Automatically converts between errors if the underlying type supports it pubfn convert<F>(e: Err<F>) -> Self where
E: From<F>,
{
e.map(crate::lib::std::convert::Into::into)
}
}
impl<T> Err<(T, ErrorKind)> { /// Maps `Err<(T, ErrorKind)>` to `Err<(U, ErrorKind)>` with the given `F: T -> U` pubfn map_input<U, F>(self, f: F) -> Err<(U, ErrorKind)> where
F: FnOnce(T) -> U,
{ matchself {
Err::Incomplete(n) => Err::Incomplete(n),
Err::Failure((input, k)) => Err::Failure((f(input), k)),
Err::Error((input, k)) => Err::Error((f(input), k)),
}
}
}
impl<T> Err<error::Error<T>> { /// Maps `Err<error::Error<T>>` to `Err<error::Error<U>>` with the given `F: T -> U` pubfn map_input<U, F>(self, f: F) -> Err<error::Error<U>> where
F: FnOnce(T) -> U,
{ matchself {
Err::Incomplete(n) => Err::Incomplete(n),
Err::Failure(error::Error { input, code }) => Err::Failure(error::Error {
input: f(input),
code,
}),
Err::Error(error::Error { input, code }) => Err::Error(error::Error {
input: f(input),
code,
}),
}
}
}
#[cfg(feature = "std")] impl<E> Error for Err<E> where
E: fmt::Debug,
{ fn source(&self) -> Option<&(dyn Error + 'static)> {
None // no underlying error
}
}
/// All nom parsers implement this trait pubtrait Parser<I, O, E> { /// A parser takes in input type, and returns a `Result` containing /// either the remaining input and the output value, or an error fn parse(&mutself, input: I) -> IResult<I, O, E>;
/// Maps a function over the result of a parser fn map<G, O2>(self, g: G) -> Map<Self, G, O> where
G: Fn(O) -> O2, Self: core::marker::Sized,
{
Map {
f: self,
g,
phantom: core::marker::PhantomData,
}
}
/// Creates a second parser from the output of the first one, then apply over the rest of the input fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O> where
G: FnMut(O) -> H,
H: Parser<I, O2, E>, Self: core::marker::Sized,
{
FlatMap {
f: self,
g,
phantom: core::marker::PhantomData,
}
}
/// Applies a second parser over the output of the first one fn and_then<G, O2>(self, g: G) -> AndThen<Self, G, O> where
G: Parser<O, O2, E>, Self: core::marker::Sized,
{
AndThen {
f: self,
g,
phantom: core::marker::PhantomData,
}
}
/// Applies a second parser after the first one, return their results as a tuple fn and<G, O2>(self, g: G) -> And<Self, G> where
G: Parser<I, O2, E>, Self: core::marker::Sized,
{
And { f: self, g }
}
/// Applies a second parser over the input if the first one failed fn or<G>(self, g: G) -> Or<Self, G> where
G: Parser<I, O, E>, Self: core::marker::Sized,
{
Or { f: self, g }
}
/// automatically converts the parser's output and error values to another type, as long as they /// implement the `From` trait fn into<O2: From<O>, E2: From<E>>(self) -> Into<Self, O, O2, E, E2> where Self: core::marker::Sized,
{
Into {
f: self,
phantom_out1: core::marker::PhantomData,
phantom_err1: core::marker::PhantomData,
phantom_out2: core::marker::PhantomData,
phantom_err2: core::marker::PhantomData,
}
}
}
impl<'a, I, O, E, F> Parser<I, O, E> for F where
F: FnMut(I) -> IResult<I, O, E> + 'a,
{ fn parse(&mutself, i: I) -> IResult<I, O, E> { self(i)
}
}
#[cfg(feature = "alloc")] use alloc::boxed::Box;
#[cfg(feature = "alloc")] impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> { fn parse(&mutself, input: I) -> IResult<I, O, E> {
(**self).parse(input)
}
}
#[test] #[cfg(target_pointer_width = "64")] fn size_test() {
assert_size!(IResult<&[u8], &[u8], (&[u8], u32)>, 40); //FIXME: since rust 1.65, this is now 32 bytes, likely thanks to https://github.com/rust-lang/rust/pull/94075 // deactivating that test for now because it'll have different values depending on the rust version // assert_size!(IResult<&str, &str, u32>, 40);
assert_size!(Needed, 8);
assert_size!(Err<u32>, 16);
assert_size!(ErrorKind, 1);
}
#[test] fn err_map_test() { let e = Err::Error(1);
assert_eq!(e.map(|v| v + 1), Err::Error(2));
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.