from_str(count_min_max::<String, _, _>(min, max, digit()))
parse::<i32>
is acceptable
and_then
like from_str
does and substitute your own message https://github.com/Marwes/combine/blob/a358c88933bb58c4df0d9a0212b4a33d2b24be7b/src/parser/combinator.rs#L1165-L1169
I did stumble onto StreamErrorFor::<Input>::other
eventually yesterday, and ended up with
fn n_digits<Input>(min: usize, max: usize) -> impl Parser<Input, Output = i32>
where
Input: Stream<Token = char>,
// Necessary due to rust-lang/rust#24159
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
count_min_max(min, max, digit()).and_then(|s: String| {
s.parse().map_err(StreamErrorFor::<Input>::other)
})
}
Which was acceptable. I'll try out from_str
tonight though and compare the error messages that they generate, looks like they may arrive at different errors, though I'm not sure how they'll differ.
captures
I get some incredible error spam that's hard to sort through.
fn main() {
let mut p =
captures(Regex::new(r"<((?:\\\\|\\>|[^>\n])*)>").unwrap())
.map(|captures: Vec<&str>| String::from(captures[1]));
let input = "<hello>";
let result = p.easy_parse(input);
match result {
Ok((value, _remaining_input)) => println!("{:?}", value),
Err(err) => println!("{}", err)
}
}
fn custom_status<Input>() -> impl Parser<Input, Output = String>
where
Input: Stream<Token = char>,
// Necessary due to rust-lang/rust#24159
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
captures(Regex::new("<(\\\\|\\>|[^>\n])>").unwrap()).map(|captures: Vec<&str>| String::from(captures[1]))
}
Goddam, I am not nearly familiar enough with Rust to be doing this, but I did figure out how to make my function compile:
/**
* Parses a status.
*/
fn custom_status<'a, Input: 'a>() -> impl Parser<Input, Output = String> + 'a
where
Input: Stream<Token = char>,
Input: RangeStreamOnce<Range = &'a str>,
// Necessary due to rust-lang/rust#24159
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
captures(Regex::new(r"<((?:\\\\|\\>|[^>\n])*)>").unwrap()).map(|captures: Vec<&str>| String::from(captures[1]))
}
I am dubious that this is the easiest way though...
i have been increasingly writing parsers that have chains of the form
.then(|val| {
value(val)
.and(.........
and I figure that there could be a combinator here that passes in the output of the previous parser as an immutable ref for dispatching but then just forwards that value through without consuming it
self.1
self.1
calls?
Error
if something's required isn't present
&str
, outputs an &str
, doesn't do extra copies, and restricts the input type as little as possible? you can find here my flailing attempt (see the symbol
function): https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ecd82417fdf8a3aaeed27e9151ef1152 help is appreciated! thanks
String
i could use map
on the output of many1
but since i want to borrow i don't know what to do