I'm trying to rewrite my parser to allow for strings to be passed into the parse method, instead of being bound to the struct.
Previously, my code looked like this:
use std::collections::HashMap;
use std::str;
#[derive(Debug)]
pub enum ParserError {
Generic
}
pub struct Resource(
pub HashMap<String, String>
);
pub struct Parser<'a> {
source: str::Chars<'a>
}
impl<'a> Parser<'a> {
pub fn new(source: &str) -> Parser {
Parser { source: source.chars() }
}
pub fn parse(&mut self) -> Result<Resource, ParserError> {
let entries = HashMap::new();
Ok(Resource(entries))
}
}
fn main() {
let parser = Parser::new("key1 = Value 1");
let res = parser.parse();
}
and in my new code I'm trying something like this:
use std::collections::HashMap;
use std::str;
#[derive(Debug)]
pub enum ParserError {
Generic
}
pub struct Resource(
pub HashMap<String, String>
);
pub struct Parser<'a> {
source: Option<str::Chars<'a>>
}
impl<'a> Parser<'a> {
pub fn new() -> Parser<'a> {
Parser { source: None }
}
pub fn parse(&mut self, source: &str) -> Result<Resource, ParserError> {
self.source = Some(source.chars());
let entries = HashMap::new();
Ok(Resource(entries))
}
}
fn main() {
let parser = Parser::new();
parser.parse("key1 = Value 1");
parser.parse("key2 = Value 2");
}
but it seems like I'm messing with lifetimes in a way that I'm not fully comfortable with. The error I get is:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> test.rs:22:35
|
22 | self.source = Some(source.chars());
|
What's the canonical way of handling this? How can I take a String and clone it into the lifetime of the Parser struct?
The full error message is:
Doing as it suggests:
Allows the code to compile and run (after fixing the unrelated mismatched mutability in
main).To understand the difference, you must first understand lifetime elision.
Your original code was:
In words, the generic lifetime parameter
'aof the struct was tied to the lifetime of the incoming string.Your new code was more complicated:
In words, the generic lifetime parameter
'aof the struct is still defined by the caller ofnew, but now it's not tied to anything from the constructor. When callingparse, you were attempting to pass in a string of an unrelated lifetime and store a reference to it (through theCharsiterator). Since the two lifetimes were unrelated, you cannot be sure it will last long enough.