I'm learning Rust and am trying to write a simple lexer. I have a function next_token
in an impl
block that reads the next token from an input character iterator. However, the code will not build because of multiple borrows of self. How do I get around this?
struct Lexer<'a> {
input: Peekable<Chars<'a>>
}
...
impl<'a> Lexer<'a> {
pub fn create(input: &str) -> Lexer {
Lexer { input: input.chars().peekable() }
}
fn next_token(&mut self) -> Option<Token> {
match self.input.by_ref().peek() {
Some(c) if c.is_alphabetic() || *c == '_' => { // Identifier or keyword
let literal = self.input.take_while(|&ch| {
match self.input.peek() {
Some(inner_c) => inner_c.is_alphanumeric() || *inner_c == '_',
None => false
}
}).collect::<String>();
if let Some(keyword) = check_keyword(&literal) { // Literal is a keyword
return Some(Token { literal: literal, token_type: keyword });
} else { // Literal is identifier
return Some(Token { literal: literal, token_type: TokenType::Identifier });
};
},
... // Other cases
}
}
}
The error I am getting:
error[E0507]: cannot move out of borrowed content --> lexer.rs:110:20 | 110 | let literal = self.input.take_while(|&ch| { | ^^^^ cannot move out of borrowed content
error[E0500]: closure requires unique access to
self
butself.input
is already borrowed --> lexer.rs:110:42 | 108 | match self.input.by_ref().peek() { | ---------- borrow occurs here 109 | Some(c) if c.is_alphabetic() || *c == '_' => { // Identifier or keyword 110 | let literal = self.input.take_while(|&ch| { | ^^^^^ closure construction occurs here 111 |
match self.input.peek() { | ---- borrow occurs due to use ofself
in closure ... 139 | } | - borrow ends here