1

I'm new to Rust and have been trying to wrap my head around this for three hours and I think I'm going insane. All I want is a parser that takes the string "true" and returns an enum Value::Const(true). This is what I have so far:

// parser.rs
use nom::*;

#[derive(PartialEq, Debug, Clone)]
pub enum Value {
    Const(bool),
}

fn true_value<T>(_: T) -> Value { Value::Const(true) }
fn false_value<T>(_: T) -> Value { Value::Const(false) }

named!(literal_true<&[u8]>, map_res!(tag!("true"), true_value));
named!(literal_false<&[u8]>, map_res!(tag!("false"), false_value));

But what I get is:

error[E0308]: mismatched types
  --> src/parser.rs:25:1
   |
25 | named!(literal_true<&[u8], Result<Value, String>>, map_res!(tag!("true"), true_value));
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `parser::Value`, found enum `std::result::Result`
   |
   = note: expected type `parser::Value`
              found type `std::result::Result<_, _>`
   = note: this error originates in a macro outside of the current crate

I have no idea what is happening here. I tried to find examples or tutorials to get just a tiny hint on how to do this, but for some reason, this must be some rare edge thing nobody else tried to do before.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Lanbo
  • 15,118
  • 16
  • 70
  • 147
  • 3
    Try compiling with `cargo rustc -- --pretty expanded -Z unstable-options`. This will show you the expanded macros. – Peter Hall May 20 '17 at 22:15

1 Answers1

4

You have two issues: the function you pass to map_res (as in map result) must return a Result, and the function signature you pass to named must indicate input and output types. If you don't want to return a result, you can use the map macro

#[derive(PartialEq, Debug, Clone)]
pub enum Value {
    Const(bool),
}

fn true_value<T>(_: T) -> Value { Value::Const(true) }
fn false_value<T>(_: T) -> Value { Value::Const(false) }

// input type and output type 
named!(literal_true<&[u8], Value>, map!(tag!("true"), true_value));
// input type can be omitted if it's &[u8]
named!(literal_false<Value>, map!(tag!("false"), false_value));
Francois Mockers
  • 713
  • 4
  • 14