rust-bakery / nom-bufreader

BufReader adapter for nom parsers
MIT License
9 stars 5 forks source link

only declared function parsers can be used #3

Open Geal opened 3 years ago

Geal commented 3 years ago

Apparently I cannot write this:

let _ = i.parse( tag("abcd").map(|_| ()) )?;

As it would result in this error:

error[E0308]: mismatched types
  --> examples/sync_http.rs:35:15
   |
35 |     let _ = i.parse(tag("abcd").map(|_| ()))?;
   |               ^^^^^ one type is more general than the other
   | 
  ::: /home/geal/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-6.2.1/src/bytes/streaming.rs:34:6
   |
34 | ) -> impl Fn(Input) -> IResult<Input, Input, Error>
   |      ----------------------------------------------
   |      |
   |      the expected opaque type
   |      the found opaque type
   |
   = note: expected associated type `<impl Fn<(&[u8],)> as FnOnce<(&[u8],)>>::Output`
              found associated type `<impl Fn<(&[u8],)> as FnOnce<(&'a [u8],)>>::Output`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `nom-bufreader` due to previous error
cheako commented 2 years ago

Perhaps related too: https://github.com/rust-lang/rust/issues/30867

cheako commented 2 years ago

Also, even declared functions have this problem???? archive.ar.txt

cheako commented 2 years ago

https://cdn.discordapp.com/attachments/909938623187664927/910229344637558885/archive.ar.txt

jobtijhuis commented 2 years ago

To summarize from the two archives @cheako posted:

Making the error manually owned works as a workaround for now:

use nom_bufreader::bufreader::BufReader;
use nom_bufreader::Parse;
use nom::error::{ContextError, Error as NomError, ErrorKind, FromExternalError, ParseError};

#[derive(Debug, PartialEq)]
struct Error(NomError<Vec<u8>>);

impl ParseError<&'_ [u8]> for Error {
    fn from_error_kind(input: &'_ [u8], kind: ErrorKind) -> Self {
        Error(NomError::from_error_kind(input.to_owned(), kind))
    }

    fn append(_: &'_ [u8], _: ErrorKind, other: Self) -> Self {
        other
    }
}
impl ContextError<&'_ [u8]> for Error {}

impl<E> FromExternalError<&'_ [u8], E> for Error {
    fn from_external_error(input: &'_ [u8], kind: ErrorKind, _e: E) -> Self {
        Error(NomError::from_external_error(input.to_owned(), kind, _e))
    }
}

fn list_ints(input: &[u8]) -> IResult<&[u8], Vec<u8>, Error> {
    separated_list0(tag(","), u8)(input)
}

But to actually fix this usability problem for declared functions see #9

Disclaimer: quite new to Rust but loving the nom parser thus far