So I've picked a pretty difficult Rust project to toy with: parser combinators. Except, I'm not getting too far. I find it difficult to figure out how to solve the lifetime errors, and it seems like the behavior of closures has changed so rapidly in the past year that any information you find will be outdated.
use std::str::Chars;
use std::iter::Peekable;
fn main() {
let input = "5+5";
let parser = chr('5');
let result = parse(&parser, &input);
println!("{}", result);
}
type InputType<'a> = Peekable<Chars<'a>>;
type Parser<'a> = Box<Fn(&'a InputType) -> ParseResult<'a> + 'static>;
struct ParseResult<'a> {
rest: &'a InputType<'a>
}
fn parse<'a>(parser: &Parser<'a>, input: &'a str) -> i64 {
let iter = input.chars().peekable();
let result = parser(&iter.clone());
1
}
fn chr<'a>(x: char) -> Parser<'a> {
Box::new(|input: &InputType<'a>| ParseResult { rest: input })
}
Here's what I'm going for. I want chr
to return a Parser
, a closure that is, which accepts a string iterator and produces some ParseResult
from that string. rest
would be a string iterator that points to the beginning of the unconsumed content of the string.
The code, as it is, breaks in a milion ways. I'm confused about why I need to box my closures, what the + 'static
syntax does, how I can reason about when to introduce new lifetime arguments to a function, and how to fix the existing lifetime errors. I think the real issue is that I have a hard time understanding how closures work in Rust, and the documentation out there is either too terse or outdated.
Any help on this is much appreciated!