Hello,
I am new to Rust and I am trying to write a pull-parser as a first project. I have defined a struct like this:
struct AbnfScanner<'a> {
source: &'a str,
iter: std::str::CharIndices<'a>,
last: Option<char>,
position: usize,
last_position: usize,
line: usize,
column: usize,
token: Token<'a>,
}
And it has some get_next
function performing the next parsing step and storing the current token. It looks like this:
impl<'a> AbnfScanner<'a> {
// ...new() and other functions not listed...
fn get_next(&mut self) -> &'a Token
{
// Modifications to self / AbnfScanner and self.token happen here...
}
}
This causes problems because I need a mutable reference to call get_next
which even cause my simple unit tests to not compile:
let token = abnf_scanner.get_next();
let expected = Token{ class: TokenClass::TokenId(AbnfTokenId::Name as u32), content: &"rule", line: 1, column: 1 };
if *token != expected {
return Err(format!("Unexpected result: {:?} \n!=\n {:?}", token, expected));
}
let token = abnf_scanner.get_next();
let expected = Token{ class: TokenClass::TokenId(AbnfTokenId::Whitespace as u32), content: &" ", line: 1, column: 5 };
if *token != expected {
return Err(format!("Unexpected result: {:?} \n!=\n {:?}", token, expected));
}
I get multiple errors like this:
error[E0499]: cannot borrow `*abnf_scanner` as mutable more than once at a time
I read RefCell<T> and the Interior Mutability Pattern - The Rust Programming Language and it looks like it would solve my problem but I wonder if it is the best way to go or if there are other solutions. Here are some thoughts and questions:
- if I use
RefCell
what is it doing, more precisely what runtime costs will that add? - I read that
RefCell
breaks the borrow checking. But that would not affect the code outside of my struct, right? - could I solve the issue by passing the struct from the outside? (meaning not using self / global functions which are not an implementation for the struct)
Sorry for this simple questions. But I have read a lot about Rust but still feel uncertain about what is the right way to go.
Thanks for your help/thoughts in advance.