-
Notifications
You must be signed in to change notification settings - Fork 114
Open
Labels
Description
Background
I have wrapped str with StrInput and StrInputSlice myself, and have impl ParseSlice for StrInput, and then I can use $() symbol to get StrInputSlice in which way I can get whole input str access. This is very nice, this is also the reason I chose rust-peg over pest.
pub struct StrInput <'a> {
pub input: &'a str,
}
pub struct StrInputSlice<'a> {
pub input: &'a str,
pub start: usize,
pub end: usize
}
impl<'a> StrInput<'a> {
pub fn new(input: &'a str) -> Self {
Self {input}
}
pub fn slice(&self, start: usize, end: usize) -> StrInputSlice {
StrInputSlice {
input: self.input,
start, end
}
}
}
impl<'a> StrInputSlice<'a> {
pub fn get_slice(&self) -> &'a str {
&self.input[self.start..self.end]
}
}
impl<'a> peg::ParseSlice<'a> for StrInput<'a> {
type Slice = StrInputSlice<'a>;
fn parse_slice(&'a self, p1: usize, p2: usize) -> Self::Slice {
self.slice(p1, p2)
}
}Problem is here
but for zero-copy reason, I also want to return sliced str from StrInput<'a> , but I got a life time error for the code below. cuz StringInputSlice is parsed by ParseSlice::parse_slice with a impilict 'input life time so that we can't return StrInputSlice with 'a lifetime
parser!(grammar test_parser<'a>() for StrInput<'a> {
/// the reason I wrap str with `StrInput` and `StrInputSlice` is here. I want a way that I can access previous chars(look behind?).
rule check_previous() = slice: $(['*']+) {?
if slice.start == 0 {
return Ok(());
}
// unwrap here is ok
let char_before = &slice.input[slice.start..slice.end].chars().rev().next().unwrap();
if *char_before != ' ' {
return Err("should preceded by space")
}
Ok(())
}
// here we got an error,
// cuz StringInputSlice is parsed by `ParseSlice::parse_slice` with a impilict `'input` life time
// so that we can't return StrInputSlice with `'a` lifetime
rule parse_slice() -> StrInputSlice<'a> = slice:$([_]*) {
slice
}
});Thoughts
- maybe
rust-pegcan add a way we can use'inputlifetime.
parser!(grammar test_parser() for StrInput<'input> {
// ...
});- add a way we can add a lifetime bound
'input: 'a
parser!(grammar test_parser2<'a>() for StrInput<'a>
where 'input: 'a
{
// ...
});or maybe both 😀