Open
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-peg
can add a way we can use'input
lifetime.
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 😀