Trait parser_compose::Parser
source · pub trait Parser<In, Out> {
// Required method
fn try_parse(&self, input: Input<In>) -> Res<In, Out>;
// Provided methods
fn map<F, Mapped>(self, f: F) -> Map<Self, F, Out>
where Self: Sized,
F: Fn(Out) -> Mapped { ... }
fn or<P>(self, next: P) -> Or<Self, P>
where Self: Sized { ... }
fn when<F>(self, pred: F) -> Predicate<Self, F>
where Self: Sized,
F: Fn(Out) -> bool { ... }
fn repeated<R: RepetitionArgument>(self, count: R) -> Repeat<Self, R>
where Self: Sized { ... }
fn optional(self) -> Optional<Self>
where Self: Sized { ... }
fn peeked(self) -> Peeked<Self>
where Self: Sized { ... }
fn not_peeked(self) -> NotPeeked<Self, Out>
where Self: Sized { ... }
fn and_then<F, U, E>(self, f: F) -> AndThen<Self, F, Out>
where Self: Sized,
F: Fn(Out) -> Result<U, E>,
E: Error { ... }
fn label(self, l: &'static str) -> Label<Self>
where Self: Sized { ... }
fn err<E, F>(self, f: F) -> UserErr<Self, F, E>
where Self: Sized,
F: Fn() -> E,
for<'a> E: Error + 'a { ... }
}
Expand description
A trait for parsers
A parser takes in input and either outputs a value or reports an error.
The Parser
trait is already implemented slices and &str
s.
Required Methods§
Provided Methods§
sourcefn map<F, Mapped>(self, f: F) -> Map<Self, F, Out>where
Self: Sized,
F: Fn(Out) -> Mapped,
fn map<F, Mapped>(self, f: F) -> Map<Self, F, Out>where Self: Sized, F: Fn(Out) -> Mapped,
Returns a parser that maps a Parser<In, Out>
to Parser<In, Mapped>
by applying a
function to the result of the parser if it succeeded.
use parser_compose::Parser;
let msg = "a";
let (value, _) = "a".map(|s| s.to_ascii_uppercase()).try_parse(msg.into()).unwrap();
assert_eq!(value, "A");
sourcefn or<P>(self, next: P) -> Or<Self, P>where
Self: Sized,
fn or<P>(self, next: P) -> Or<Self, P>where Self: Sized,
Returns a parser that succeeds if self
does. Otherwise, it’s outcome is that of next
.
use parser_compose::Parser;
let msg = "a";
let (value, _) = "1".or("a").try_parse(msg.into()).unwrap();
assert_eq!(value, "a");
sourcefn when<F>(self, pred: F) -> Predicate<Self, F>where
Self: Sized,
F: Fn(Out) -> bool,
fn when<F>(self, pred: F) -> Predicate<Self, F>where Self: Sized, F: Fn(Out) -> bool,
Returns a new parser that succeeds if the predicate returns true
. The predicate is given the
extracted value of the current parser as an argument
use parser_compose::{any_str,Parser};
let msg = "boo";
let (value, _) = any_str.when(|s| s == "b").try_parse(msg.into()).unwrap();
assert_eq!(value, "b");
sourcefn repeated<R: RepetitionArgument>(self, count: R) -> Repeat<Self, R>where
Self: Sized,
fn repeated<R: RepetitionArgument>(self, count: R) -> Repeat<Self, R>where Self: Sized,
Returns a parser that suceeds if it is able to repeat count
times.
count
can be:
- A single
usize
(e.g.8
): The parser will try to match at least 8 times and return aVec
of length 8 if it succeeds
use parser_compose::Parser;
let msg = "AAAA";
let (value, rest) = "A".repeated(3).try_parse(msg.into()).unwrap();
assert_eq!(value, vec!["A", "A", "A"]);
assert_eq!(rest, "A");
- A range bounded inclusively from below (e.g.
3..
): The parser will try to match at least 3 times, but possibly more. If it succeeds, the returnedVec
is be guaranteed to have a value greater than 3.
use parser_compose::Parser;
let msg = "AAAA";
let (value, rest) = "A".repeated(2..).try_parse(msg.into()).unwrap();
assert_eq!(value, vec!["A", "A", "A", "A"]);
assert_eq!(rest, "");
- A range bounded inclusively from above (e.g.
..=4
): The parser will try to match at most 4 times, but possibly less (including zero times!). If it succeeds, the returnedVec
will have at most 4 elements
use parser_compose::Parser;
let msg = "AA";
let (value, rest) = "A".repeated(..=4).try_parse(msg.into()).unwrap();
assert_eq!(value, vec!["A", "A"]);
assert_eq!(rest, "");
- A range bounded inclusively from above and below (e.g.
3..=5
): The parser will try to match at least 3 times and at most 5 times. If it succeeds, the returnedVec
will have a length between 3 and 5
use parser_compose::Parser;
let msg = "AAAA";
let (value, rest) = "A".repeated(2..=3).try_parse(msg.into()).unwrap();
assert_eq!(value, vec!["A", "A", "A"]);
assert_eq!(rest, "A");
sourcefn optional(self) -> Optional<Self>where
Self: Sized,
fn optional(self) -> Optional<Self>where Self: Sized,
Returns a parser always succeeds but wraps the output in an Option<Out>
. If the original
parser would have failed, the parser outputs a None
.
use parser_compose::Parser;
let msg = "a";
let ((b, a), _) = ("b".optional(), "a").try_parse(msg.into()).unwrap();
assert_eq!(b, None);
assert_eq!(a, "a");
sourcefn peeked(self) -> Peeked<Self>where
Self: Sized,
fn peeked(self) -> Peeked<Self>where Self: Sized,
Returns a parser that succeeds or fails as normal, but never consumes any input regardless of the outcome. This can be used to look ahead.
use parser_compose::Parser;
// Recognize the sequence "a" followed by "b", but only if it is followed by a "c"
let a_then_b = ("a", "b", "c".peeked());
let (value, rest) = a_then_b.try_parse("abc".into()).unwrap();
// note: the value gets recognized and returned, but it does not consume it.
assert_eq!(value, ("a".to_string(), "b".to_string(), "c".to_string()));
assert_eq!(rest, "c");
let result = a_then_b.try_parse("abb".into());
assert!(result.is_err());
sourcefn not_peeked(self) -> NotPeeked<Self, Out>where
Self: Sized,
fn not_peeked(self) -> NotPeeked<Self, Out>where Self: Sized,
Reverse of peeked()
. Returns a parse that succeeds if it was not
able to recognize the input and fails if it was able to. It never consumes any input.
use parser_compose::Parser;
// This parser matches "foo", but only if it is not followed by "bar"
let parser = ("foo", "bar".not_peeked());
let msg = "foobar";
let result = parser.try_parse(msg.into());
assert!(result.is_err());
let (value, rest) = parser.try_parse("foobaz".into()).unwrap();
assert_eq!(value, (String::from("foo"), ()));
assert_eq!(rest, "baz");
sourcefn and_then<F, U, E>(self, f: F) -> AndThen<Self, F, Out>where
Self: Sized,
F: Fn(Out) -> Result<U, E>,
E: Error,
fn and_then<F, U, E>(self, f: F) -> AndThen<Self, F, Out>where Self: Sized, F: Fn(Out) -> Result<U, E>, E: Error,
Returns a parser that is similar to map()
in its behavior, except
that the provided closure may fail. The parser reports whatevere error the closure fails
with.
use parser_compose::{Parser};
let msg = [98].as_slice();
let (value, _) = [98].and_then(|b| {
// converting to utf8 can fail
String::from_utf8(b)
}).try_parse(msg.into()).unwrap();
assert_eq!("b", value);
Implementations on Foreign Types§
source§impl<'input, 'pat> Parser<&'input str, String> for &'pat str
impl<'input, 'pat> Parser<&'input str, String> for &'pat str
The Parser
trait is implemented for string slices, which means all &str
s
will have the try_parse()
method. Calling it will try to do a prefix match of the input with
the &str
used as the pattern.
use parser_compose::Parser;
let msg = "HELLO";
let (res, rest) = "HE".try_parse(msg.into()).unwrap();
assert_eq!(res, "HE");
assert_eq!(rest, "LLO");
source§impl<'pat, 'input, T> Parser<&'input [T], Vec<T>> for &'pat [T]where
T: PartialEq + Clone + Debug,
impl<'pat, 'input, T> Parser<&'input [T], Vec<T>> for &'pat [T]where T: PartialEq + Clone + Debug,
The Parser
trait is implemented for all slices, which means all &[T]
will have the
try_parse()
method. Calling it will try to do a prefix match of the input with the slice used
as the pattern.
use parser_compose::Parser;
let msg = &['H', 'E', 'L', 'L', 'O'][..];
let (res, rest) = ['H', 'E'].as_slice().try_parse(msg.into()).unwrap();
assert_eq!(res, &['H', 'E'][..]);
assert_eq!(rest, &['L', 'L', 'O'][..]);
source§impl<In, P0, O0> Parser<In, (O0,)> for (P0,)where
P0: Parser<In, O0>,
impl<In, P0, O0> Parser<In, (O0,)> for (P0,)where P0: Parser<In, O0>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1> Parser<In, (O0, O1)> for (P0, P1)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
impl<In, P0, O0, P1, O1> Parser<In, (O0, O1)> for (P0, P1)where P0: Parser<In, O0>, P1: Parser<In, O1>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2> Parser<In, (O0, O1, O2)> for (P0, P1, P2)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
impl<In, P0, O0, P1, O1, P2, O2> Parser<In, (O0, O1, O2)> for (P0, P1, P2)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3> Parser<In, (O0, O1, O2, O3)> for (P0, P1, P2, P3)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3> Parser<In, (O0, O1, O2, O3)> for (P0, P1, P2, P3)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4> Parser<In, (O0, O1, O2, O3, O4)> for (P0, P1, P2, P3, P4)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4> Parser<In, (O0, O1, O2, O3, O4)> for (P0, P1, P2, P3, P4)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5> Parser<In, (O0, O1, O2, O3, O4, O5)> for (P0, P1, P2, P3, P4, P5)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5> Parser<In, (O0, O1, O2, O3, O4, O5)> for (P0, P1, P2, P3, P4, P5)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6> Parser<In, (O0, O1, O2, O3, O4, O5, O6)> for (P0, P1, P2, P3, P4, P5, P6)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6> Parser<In, (O0, O1, O2, O3, O4, O5, O6)> for (P0, P1, P2, P3, P4, P5, P6)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7)> for (P0, P1, P2, P3, P4, P5, P6, P7)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
P7: Parser<In, O7>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7)> for (P0, P1, P2, P3, P4, P5, P6, P7)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
P7: Parser<In, O7>,
P8: Parser<In, O8>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
P7: Parser<In, O7>,
P8: Parser<In, O8>,
P9: Parser<In, O9>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
P7: Parser<In, O7>,
P8: Parser<In, O8>,
P9: Parser<In, O9>,
P10: Parser<In, O10>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>, P10: Parser<In, O10>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
source§impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10, P11, O11> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)where
P0: Parser<In, O0>,
P1: Parser<In, O1>,
P2: Parser<In, O2>,
P3: Parser<In, O3>,
P4: Parser<In, O4>,
P5: Parser<In, O5>,
P6: Parser<In, O6>,
P7: Parser<In, O7>,
P8: Parser<In, O8>,
P9: Parser<In, O9>,
P10: Parser<In, O10>,
P11: Parser<In, O11>,
impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10, P11, O11> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>, P10: Parser<In, O10>, P11: Parser<In, O11>,
A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on
Calling the .try_parse()
on the tuple returns a new tuple containing the extracted values.
This is implemented for tuples up to 12 items long
Implementors§
impl<'input> Parser<&'input str, String> for AsciiStr
impl<'input> Parser<&'input [u8], Vec<u8>> for Byte
impl<In, Out, E, P, F, U> Parser<In, U> for AndThen<P, F, Out>where P: Parser<In, Out>, F: Fn(Out) -> Result<U, E>, for<'a> E: Error + 'a,
impl<In, Out, F> Parser<In, Out> for Fwhere F: Fn(Input<In>) -> Res<In, Out>,
The Parser
trait is automatically implemented for any function with
the following signature:
Fn(Input<In>) -> parser_compose::Res<In, Out>
See the trait documentation for more info about the type parameters.