So I have this procedure that I think needs to be looked at first
fn pchar<'a, I, E>()
-> impl Fn(I) -> nom::IResult<I, I, E>
where I: 'a + Clone + nom::InputTake + nom::Compare<&'static str> + nom::InputIter + nom::InputLength + nom::InputTakeAtPosition + std::iter::ExactSizeIterator + std::ops::Index<usize>,
<I as nom::InputTakeAtPosition>::Item: nom::AsChar,
<I as std::ops::Index<usize>>::Output: Sized,
E: nom::ParseError<I>
{
let homogenize_pct_encoded = |i: ((I, I), I)| {
// Params `I` will always be utf-8 byte length string. Expand the first slice to
// include the value from the other slices so we dont have to use a Vec. So
// long as the slices are contiguous, this wont actualyl be unsafe.
let ptr = &(i.0).0[0] as *const _;
let contiguous_matches = unsafe {
// All slices are non overlapping, contiguous sub arrays of a greater array.
// ptr starts at first slice's first element and expands by the length
// of itself + next slice + last slice
//
// [..., s1[0] -------- -------- -------- ]
// ptr s1 len s2 len s3 len
std::slice::from_raw_parts(ptr, (i.0).0.len() + (i.0).1.len() + (i.1).len())
};
// We are returning a contiguous result so parsed results must be contiguous
// so we dont accidently use a parser that gives discontiguous results
// COMMENTING OUT TEMPORARILY SO WE DONT NEED TO DEAL WITH DEBUG IMPLS FOR NOW
//debug_assert_eq!(&contiguous_matches[0..(i.0).0.len()], (i.0).0);
//debug_assert_eq!(&contiguous_matches[(i.0).0.len()..(i.0).0.len() + (i.0).1.len()], (i.0).1);
//debug_assert_eq!(&contiguous_matches[(i.0).0.len() + (i.0).1.len()..(i.0).0.len() + (i.0).1.len() + (i.1).len()], i.1);
// TODO: Should also debug_assert that the slices are not overlapping, but
// even non overlapping slices can have the same values, so not sure how to test.
// Maybe match ptr values?
contiguous_matches
};
alt((
unreserved(),
nom::map(pct_encoded(), homogenize_pct_encoded),
sub_delims(),
tag(":"),
tag("@"),
))
}
So what I'm doing here is attempting to parse an array of characters using pchar(). The return type as you can see is impl Fn(I) -> nom::IResult<I, I, E>
. That's what the alt() function call returns there at the end.
Now I need that homogenize_pct_encoded
lambda. All the types in the tuple going into alt()
have to be the same, so we "homogenize" the one from the pct_encoded()
parser. I can totally justify what I'm doing here, but let me get to the problem.
Compiling, I get back the message
--> src/lib.rs:386:5
|
386 | alt((
| ^^^ expected &[_], found type parameter
|
= note: expected type `std::result::Result<(I, &[_]), nom::Err<_>>`
found type `std::result::Result<(I, I), nom::Err<_>>`
= note: required because of the requirements on the impl of `nom::branch::Alt<I, I, _>` for `(impl std::o
ps::Fn<(I,)>, impl std::ops::Fn<(I,)>, impl std::ops::Fn<(I,)>, impl std::ops::Fn<(I,)>, impl std::ops::Fn<(I
,)>)`
= note: required by `nom::branch::alt`
Which means to me that the return type of homogenize_pct_encoded
is &[_]
and of course our alt()
and our pchar()
functions expect to return Result<(I, I), Err>
so all the Fn(I) -> IResult..
arguments inside our alt(( .... ))
call need to return Result<(I, I), Err>
. They all do, except for nom::map(pct_encoded(), homogenize_pct_encoded)
. It returns Result<(I, &[_]), Err>
because the homogenize_pct_encoded
returns &[_]
.
How can I make homogenize_pct_encoded
return the type I
instead of &[_]
?