-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Propagated error type. #413
Conversation
- Error types are implicitly passed around. - Some macros are currently broken (delimited!) Fixed: many1, many0, separated_list, separated_nonempty_list. - Tests which use assert_eq!(mac!(&b"input"[..], arg)); was broken, and fixed. - Fixed some tests which was wrong in error type. (Child matcher might return same error type. If not, caller must use .map_err() )
hi! before going further, can you add tests to confirm that it fixes the issue? And explain how it works? |
assert_eq!(take_bits!( (sl, 0), u32, 20 ), IResult::Done((&sl[2..], 4), 700163)); | ||
assert_eq!(take_bits!( (sl, 4), u32, 20 ), IResult::Done((&sl[3..], 0), 716851)); | ||
assert_eq!(take_bits!( (sl, 4), u32, 22 ), IResult::Incomplete(Needed::Size(22))); | ||
assert_eq!(take_bits!( (sl, 0), u8, 0 ), done((sl, 0), 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you replace IResult::Done
with done
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As commented below, type cannot be inferred if macro is used directly from assert_eq!()
$crate::IResult::Error(_) => { | ||
alt!(__impl $i, $($rest)*) | ||
$crate::IResult::Error(_alt_err) => { | ||
$crate::propagate_error_type(_alt_err, alt!(__impl $i, $($rest)*)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit uneasy about this. Especially, I don't know how it will interact with the whitespace parsing combinators
@@ -17,6 +17,13 @@ pub trait InputLength { | |||
fn input_len(&self) -> usize; | |||
} | |||
|
|||
impl<T> InputLength for [T] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about it. Maybe crlf? I configured vscode to use lf always, but it somehow prefers crlf. I'll try to remove it from pull request.
@@ -235,7 +235,7 @@ pub fn slice_to_offsets(input: &[u8], s: &[u8]) -> (usize, usize) { | |||
|
|||
#[cfg(not(feature = "core"))] | |||
#[cfg(feature = "verbose-errors")] | |||
pub fn prepare_errors<O,E: Clone>(input: &[u8], res: IResult<&[u8],O,E>) -> Option<Vec<(ErrorKind<E>, usize, usize)> > { | |||
pub fn prepare_errors<O,E: Clone>(input: &[u8], res: IResult<&[u8], O, E>) -> Option<Vec<(ErrorKind<E>, usize, usize)> > { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please avoid cosmetic changes in unrelated parts of the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry for that. It's a mistake done while experimenting,
@@ -98,7 +98,9 @@ fn issue_142(){ | |||
|
|||
#[test] | |||
fn usize_length_bytes_issue(){ | |||
length_bytes!(b"012346", be_u16); | |||
named!(typed_iresult, length_bytes!(be_u16)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why touch that test?
@@ -40,5 +40,6 @@ fn is_not() { | |||
#[test] | |||
fn exported_public_method_defined_by_macro() { | |||
let a = &b"ab12cd\nefgh"[..]; | |||
assert_eq!(not_line_ending(a), IResult::Done(&b"\nefgh"[..], &b"ab12cd"[..])); | |||
let expected: IResult<_, _> = IResult::Done(&b"\nefgh"[..], &b"ab12cd"[..]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why change that test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default parameter does not works for function, so return types for codes that calls macro directly from assert_eq() cannot be inferred.
In real world usecase, it would not affect any usage, unless users write code like
assert_eq!(macro_in_nom!("args.."), Done(...))
I'm stucked while making escaped function. Does original macro accept only slices? And it seems to match against u8, but matching non-ascii character as byte isn't safe for utf8. UTF8 extended characters have 1 on it's first bit for ascii-compatibility, so it's safe to match as byte only if it's in [0, 127]. I have a proposal about it. Implementation would be pub trait FirstChar {
fn first_char<E>() -> IResult<Self, char, E>
}
// alternative
pub trait AsChars {
type CharIter;
fn as_chars(&self) -> Self::CharIter;
}
/// maybe result. 'Incomplete' is exactly
fn decode_utf8<E>(i: &[u8]) -> IResult<&[u8], char, E> {
// ...
}
// in char related matchers
fn use_it(i: I) {
let index = sub_parser(i);
// handle incomplete from char decoding
i.slice(index..).first_char()
}
In this way, also &str can be used for it. Edit: added questions about usage of char. |
ok, sorry for the delay, I will now get to work on this :) escaped cannot work yet with &str, I planned to do that for 2.0, but didn't have the time to do it: #300 |
fixing inference for escaped will be difficult :/ |
I really don't know how to fix that one, except by specifying the type directly like this: I found a better way to write escaped in the process, though |
I have to stop for today. I have a feeling the solution will be in fixing the error type for basic parsers like alpha or tag, and let users do their fix_error above them, instead of trying to adapt in a parent parser to the custom error type coming from the child parser. |
I'm really sorry, but I can't help because I'm far away from my home and I can't use any pc. I agree that propagating error types from basical parsers is much important task. |
@kdy1997 why did you close this PR? |
Oh.. sorry for my mistake. I think I accidentally touched it while reading from mobile. |
ok, I'm relieved :) |
Any news on this? Florent |
hey, so, there was a huge refactoring for nom 4 to fix this issue, so I don't think I'll be able to merge that PR in the end. Thank you for your work still! |
Error types are implicitly passed around, and gives hints about type of error to rustc.
Fixes #302 #308 #394
Some macros are currently broken.
Fix:
I need some help to fix delimited!(), what does tuple_parser!() do?
How can I get it's error value?