This is probably an obvious newbie question. I'm writing a parser for a simple scripting language. I've got the tokenizer working; it takes an iterator over Result<char, E>
, where E is any Error type, and produces an iterator over Result<Token, TokensError<E>>
. Now I'd like to add a convenience method to create a tokenizer from a simple iterator over char
s. Here's an excerpt from my code:
impl<'a, E: Error, C: Iterator<Item=Result<char, E>>> Tokens<'a, C> {
pub fn new(filename: &'a str, chars: C) -> Tokens<'a, C> {
Tokens {
points: Points {
chars: chars,
pos: Position {
filename: filename,
line: 0,
column: 0
}
}
}
}
}
impl<'a, C: Iterator<Item=Result<char, ParseError>>> Tokens<'a, C> {
pub fn from_chars<H: Iterator<Item=char>>(filename: &'a str, chars: H) -> Tokens<'a, C> {
Tokens::new(filename, chars.map(|x| -> Result<char, ParseError> { Ok(x) }))
}
}
When I try to compile it, I get this:
src/tokenizer.rs:68:31: 68:83 error: mismatched types [E0308]
src/tokenizer.rs:68 Tokens::new(filename, chars.map(|x| -> Result<char, ParseError> { Ok(x) }))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/tokenizer.rs:68:31: 68:83 help: run `rustc --explain E0308` to see a detailed explanation
src/tokenizer.rs:68:31: 68:83 note: expected type `C`
src/tokenizer.rs:68:31: 68:83 note: found type `std::iter::Map<H, [closure@src/tokenizer.rs:68:41: 68:82]>`
Okay, it's clear enough why this isn't working. But I can't just write Tokens<'a, std::iter::Map<H, [closure@src/tokenizer.rs:68:41: 68:82]>>
. How do I tell the compiler that I want to return the type it looks like I'm returning?