pub trait IntoParser {
type Into;
Show 19 methods
// Required method
fn into_parser(self) -> Self::Into;
// Provided methods
fn seq<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> SeqParser<Self::Into, RhsParser::Into>
where Self: Sized { ... }
fn repeat<RangeTypeIncludeInteger>(
self,
range: RangeTypeIncludeInteger,
) -> RepeatParser<Self::Into, RangeTypeIncludeInteger::Into>
where Self: Sized,
RangeTypeIncludeInteger: ToCopyable,
RangeTypeIncludeInteger::Into: RangeBound<usize> { ... }
fn or<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> OrParser<Self::Into, RhsParser::Into>
where Self: Sized { ... }
fn map<ClosureType>(
self,
callback: ClosureType,
) -> MapParser<Self::Into, ClosureType>
where Self: Sized { ... }
fn void(self) -> VoidParser<Self::Into>
where Self: Sized { ... }
fn optional(self) -> OptionalParser<Self::Into>
where Self: Sized { ... }
fn optional_or<Output: Clone>(
self,
output: Output,
) -> OptionalOrParser<Self::Into, Output>
where Self: Sized { ... }
fn or_else<Closure>(
self,
closure: Closure,
) -> OptionalOrElseParser<Self::Into, Closure>
where Self: Sized { ... }
fn not<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> NotParser<Self::Into, RhsParser::Into>
where Self: Sized { ... }
fn output<Output: Clone>(
self,
output: Output,
) -> OutputParser<Self::Into, Output>
where Self: Sized { ... }
fn string(self) -> StringParser<Self::Into>
where Self: Sized,
Self::Into: for<'a> Parser<Chars<'a>> { ... }
fn vec<T>(self) -> VecParser<Self::Into>
where Self: Sized,
Self::Into: for<'a> Parser<Cloned<Iter<'a, T>>> { ... }
fn not_consume(self) -> NotConsumeParser<Self::Into>
where Self: Sized { ... }
fn reduce_left<RhsParser, Reducer>(
self,
rhs: RhsParser,
reducer: Reducer,
) -> ReduceLeftParser<Self::Into, RhsParser::Into, Reducer>
where Self: Sized,
RhsParser: IntoParser { ... }
fn reduce_right<LhsParser, Reducer>(
self,
lhs: LhsParser,
reducer: Reducer,
) -> ReduceRightParser<LhsParser::Into, Self::Into, Reducer>
where Self: Sized,
LhsParser: IntoParser { ... }
fn reduce_with<Init, Reducer>(
self,
init: Init,
reducer: Reducer,
) -> ReduceInitParser<Self::Into, Init, Reducer>
where Self: Sized,
Init: Clone { ... }
fn reduce_right_with<Init, Reducer>(
self,
init: Init,
reducer: Reducer,
) -> ReduceRightInitParser<Self::Into, Init, Reducer>
where Self: Sized,
Init: Clone { ... }
fn inspect<ClosureType>(
self,
closure: ClosureType,
) -> InspectParser<Self::Into, ClosureType>
where Self: Sized,
ClosureType: Fn() { ... }
}Expand description
Trait for converting possible types to Parser object.
This trait contains useful member functions for parser generation.
Required Associated Types§
Required Methods§
Sourcefn into_parser(self) -> Self::Into
fn into_parser(self) -> Self::Into
convert self to Parser
§Example
use rusty_parser as rp;
use rp::IntoParser;
let hello_parser = "hello".into_parser();
let a_parser = 'a'.into_parser();
let digit_parser = ('0'..='9').into_parser();Provided Methods§
Sourcefn seq<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> SeqParser<Self::Into, RhsParser::Into>where
Self: Sized,
fn seq<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> SeqParser<Self::Into, RhsParser::Into>where
Self: Sized,
concatenate two parser
Output: ( A0, A1, ..., B0, B1, ..., C0, C1, ... )
where (A0, A1, ...) are the output of the first parser,
and (B0, B1, ...), (C0, C1, ...) are the output of the following parsers.
§Example
use rusty_parser as rp;
use rp::IntoParser;
// 'a', and then 'b'
let ab_parser = rp::seq!('a', 'b', 'c'); // IntoParser for char
let res = rp::parse(&ab_parser, "abcd".chars());
assert_eq!(res.output.unwrap(), ('a', 'b', 'c')); // Output is concatenated
assert_eq!(res.it.collect::<String>(), "d");Sourcefn repeat<RangeTypeIncludeInteger>(
self,
range: RangeTypeIncludeInteger,
) -> RepeatParser<Self::Into, RangeTypeIncludeInteger::Into>
fn repeat<RangeTypeIncludeInteger>( self, range: RangeTypeIncludeInteger, ) -> RepeatParser<Self::Into, RangeTypeIncludeInteger::Into>
repeat parser multiple times. This tries to match as long as possible.
Output:
- if
Outputof the repeated parser is(), thenOutputis() - if
Outputof the repeated parser is(T,), thenOutputis(Vec<T>,) - otherwise,
(Vec<Output of Self>,)
§Example
use rusty_parser as rp;
use rp::IntoParser;
// repeat 'a' 3 to 5 times
let multiple_a_parser = 'a'.repeat(3..=5);
let res = rp::parse(&multiple_a_parser, "aaaabcd".chars());
// four 'a' is parsed
assert_eq!(res.output.unwrap(), (vec!['a', 'a', 'a', 'a',],));
assert_eq!(res.it.collect::<String>(), "bcd");
let multiple_a_parser = 'a'.repeat(3usize);
let res = rp::parse(&multiple_a_parser, "aaaabcd".chars());
// three 'a' is parsed
assert_eq!(res.output.unwrap(), (vec!['a', 'a', 'a'],));Sourcefn or<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> OrParser<Self::Into, RhsParser::Into>where
Self: Sized,
fn or<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> OrParser<Self::Into, RhsParser::Into>where
Self: Sized,
or combinator for two parsers
Output: Output of the all parsers.
Note that the output of all parsers must be the same type.
§Example
use rusty_parser as rp;
use rp::IntoParser;
// 'a' or 'b'
let ab_parser = rp::or!('a', 'b'); // IntoParser for char
// 'a' is matched
let res = rp::parse(&ab_parser, "abcd".chars());
assert_eq!(res.output.unwrap(), ('a',)); // Output of 'a'
assert_eq!(res.it.clone().collect::<String>(), "bcd");
// continue parsing from the rest
// 'a' is not matched, but 'b' is matched
let res = rp::parse(&ab_parser, res.it);
assert_eq!(res.output.unwrap(), ('b',));
assert_eq!(res.it.clone().collect::<String>(), "cd");
// continue parsing from the rest
// 'a' is not matched, 'b' is not matched; failed
let res = rp::parse(&ab_parser, res.it);
assert_eq!(res.output, None);
assert_eq!(res.it.clone().collect::<String>(), "cd");Sourcefn map<ClosureType>(
self,
callback: ClosureType,
) -> MapParser<Self::Into, ClosureType>where
Self: Sized,
fn map<ClosureType>(
self,
callback: ClosureType,
) -> MapParser<Self::Into, ClosureType>where
Self: Sized,
Map parser’s Output to new value.
Parser’s Output will be unpacked and passed to the closure. The value returned from the closure will be new Output.
Output: (T,) where T is return type of the closure.
The value v returned from the closure will be wrapped into (v,).
§Example
use rusty_parser as rp;
use rp::IntoParser;
// map the output
// <Output of 'a'> -> i32
let int_parser = 'a'.map(|ch| -> i32 { ch as i32 - 'a' as i32 });
let res = rp::parse(&int_parser, "abcd".chars());
assert_eq!(res.output.unwrap(), (0,));
assert_eq!(res.it.collect::<String>(), "bcd");Sourcefn void(self) -> VoidParser<Self::Into>where
Self: Sized,
fn void(self) -> VoidParser<Self::Into>where
Self: Sized,
Change Parser’s Output to ().
This internally call crate::match_pattern() instead of crate::parse()
Output: ()
§Example
use rusty_parser as rp;
use rp::IntoParser;
let expensive_parser = 'a'.map(|_| -> i32 {
// some expensive operations for data extracting...
panic!("This should not be called");
});
let expensive_parser = expensive_parser.void();
// ignore the output of parser
// this internally calls 'match_pattern(...)' instead of 'parse(...)'
let res = rp::parse(&expensive_parser, "abcd".chars());
assert_eq!(res.output.unwrap(), ());
assert_eq!(res.it.collect::<String>(), "bcd");Sourcefn optional(self) -> OptionalParser<Self::Into>where
Self: Sized,
fn optional(self) -> OptionalParser<Self::Into>where
Self: Sized,
This parser always success whether the input is matched or not.
Output:
- if
Outputof the origin parser is(T0,),(Option<T0>,) - otherwise,
( Option<Output of Self>, )
§Example
use rusty_parser as rp;
use rp::IntoParser;
let a_optional_parser = 'a'.optional(); // (Option<char>,)
let res = rp::parse(&a_optional_parser, "abcd".chars()); // success
assert_eq!(res.output.unwrap(), (Some('a'),));
let res = rp::parse(&a_optional_parser, "bcd".chars()); // success, but 'a' is not matched
assert_eq!(res.output.unwrap(), (None,));Sourcefn optional_or<Output: Clone>(
self,
output: Output,
) -> OptionalOrParser<Self::Into, Output>where
Self: Sized,
fn optional_or<Output: Clone>(
self,
output: Output,
) -> OptionalOrParser<Self::Into, Output>where
Self: Sized,
This parser always success whether the input is matched or not. If it failed, the given value will be returned.
Output:
<Output of Self>.
The value given to optional_or must match with the Output of the origin parser.
For single-value-output ( which’s output is (T,) ),
passing either T or (T,) is permitted.
§Example
use rusty_parser as rp;
use rp::IntoParser;
// if 'a' failed, return 'x'
let a_optional_or = 'a'.optional_or('x'); // (char,)
let res = rp::parse(&a_optional_or, "bcd".chars());
assert_eq!(res.output.unwrap(), ('x',));Sourcefn or_else<Closure>(
self,
closure: Closure,
) -> OptionalOrElseParser<Self::Into, Closure>where
Self: Sized,
fn or_else<Closure>(
self,
closure: Closure,
) -> OptionalOrElseParser<Self::Into, Closure>where
Self: Sized,
This parser always success whether the input is matched or not. If it failed, the given closure will be evaluated and returned.
Output:
<Output of Self>.
The value given to or_else must match with the Output of the origin parser.
For single-value-output ( which’s output is (T,) ),
returning either T or (T,) is permitted.
§Example
use rusty_parser as rp;
use rp::IntoParser;
// if 'a' failed, return 'x'
let a_or_else = 'a'.or_else(|| 'x'); // (char,)
let res = rp::parse(&a_or_else, "bcd".chars());
assert_eq!(res.output.unwrap(), ('x',));Sourcefn not<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> NotParser<Self::Into, RhsParser::Into>where
Self: Sized,
fn not<RhsParser: IntoParser>(
self,
rhs: RhsParser,
) -> NotParser<Self::Into, RhsParser::Into>where
Self: Sized,
Match for parser1 but not parser2.
Output: Output of Self
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser_except_4 = ('0'..='9').not('4');
let res = rp::parse(&digit_parser_except_4, "3".chars());
assert_eq!(res.output.unwrap(), ('3',));
let res = rp::parse(&digit_parser_except_4, "4".chars());
assert_eq!(res.output, None);Sourcefn output<Output: Clone>(
self,
output: Output,
) -> OutputParser<Self::Into, Output>where
Self: Sized,
fn output<Output: Clone>(
self,
output: Output,
) -> OutputParser<Self::Into, Output>where
Self: Sized,
Change Parser’s Output to (output,).
Output: (T,) where T is the type of the value you provided.
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser = ('0'..='9').output(2024);
let res = rp::parse(&digit_parser, "123456hello_world".chars());
assert_eq!(res.output.unwrap(), (2024,));
assert_eq!(res.it.collect::<String>(), "23456hello_world");Sourcefn string(self) -> StringParser<Self::Into>
fn string(self) -> StringParser<Self::Into>
Returns String of parsed input.
Only works for parsing with std::str::Chars.
Output: (String,)
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digits_parser = ('0'..='9').repeat(0..).string();
let res = rp::parse(&digits_parser, "123456hello_world".chars());
assert_eq!(res.output.unwrap(), ("123456".to_string(),));
assert_eq!(res.it.collect::<String>(), "hello_world");Sourcefn vec<T>(self) -> VecParser<Self::Into>
fn vec<T>(self) -> VecParser<Self::Into>
Returns Vec\<T\> of parsed input.
Only works for parsing with ExactSizeIterator.
Output: (Vec<Iterator::Item>,)
§Example
use rusty_parser as rp;
use rp::IntoParser;
let hello_bytes = &[104, 101, 108, 108, 111];
let hello_parser = hello_bytes.into_parser().vec::<u8>();
let res = rp::parse(&hello_parser, "hello_world1234".as_bytes().iter().copied());
assert_eq!(res.output.unwrap(), (hello_bytes.iter().cloned().collect::<Vec<u8>>(),) );Sourcefn not_consume(self) -> NotConsumeParser<Self::Into>where
Self: Sized,
fn not_consume(self) -> NotConsumeParser<Self::Into>where
Self: Sized,
Parser will not consume the input iterator. It still matches and return the output.
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser = ('0'..='9').not_consume();
let res = rp::parse(&digit_parser, "12345".chars());
assert_eq!(res.output.unwrap(), ('1',));
assert_eq!(res.it.collect::<String>(), "12345"); // iterator is not consumedSourcefn reduce_left<RhsParser, Reducer>(
self,
rhs: RhsParser,
reducer: Reducer,
) -> ReduceLeftParser<Self::Into, RhsParser::Into, Reducer>where
Self: Sized,
RhsParser: IntoParser,
fn reduce_left<RhsParser, Reducer>(
self,
rhs: RhsParser,
reducer: Reducer,
) -> ReduceLeftParser<Self::Into, RhsParser::Into, Reducer>where
Self: Sized,
RhsParser: IntoParser,
Reduce the output of the parser with the given reducer.
With given input string self rhs rhs rhs rhs ... and the reducer f,
the output will be calculated as
f( f( f(self,rhs), rhs ), rhs ), ...
§Note
-
The signature of the reducer must be
Fn(A0, A1, A2, ..., B0, B1, B2, ...) -> ( A0, A1, A2 ... ). Where(A0, A1, A2, ...)are the output of the first parser, and(B0, B1, B2, ...)are the output of the following parser. -
For single-value-output ( which’s output is
(T,)), returning eitherTor(T,)is permitted.
Output: Output of Self
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser = ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
let reduced_left = digit_parser.reduce_left(digit_parser, |lhs, rhs| lhs * 10 + rhs);
let res = rp::parse( &reduced_left, "123456abcd".chars() );
assert_eq!(res.output.unwrap(), (123456,));Sourcefn reduce_right<LhsParser, Reducer>(
self,
lhs: LhsParser,
reducer: Reducer,
) -> ReduceRightParser<LhsParser::Into, Self::Into, Reducer>where
Self: Sized,
LhsParser: IntoParser,
fn reduce_right<LhsParser, Reducer>(
self,
lhs: LhsParser,
reducer: Reducer,
) -> ReduceRightParser<LhsParser::Into, Self::Into, Reducer>where
Self: Sized,
LhsParser: IntoParser,
Reduce the output of the parser with the given reducer.
With given input string lhs lhs lhs lhs ... self and the reducer f,
the output will be calculated as
f(lhs, f(lhs, f(lhs, f( ... f(lhs,self)))
§Note
-
The signature of the reducer must be
Fn(A0, A1, A2, ..., B0, B1, B2, ...) -> ( B0, B1, B2 ... ). Where(A0, A1, A2, ...)are the output of the first parser, and(B0, B1, B2, ...)are the output of the following parser. -
For single-value-output ( which’s output is
(T,)), returning eitherTor(T,)is permitted.
Output: Output of Self
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser =
('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
let alphabet_parser =
('a'..='z').into_parser().map(|val: char| -> i32 { val as i32 - 'a' as i32 });
let reduced_right =
alphabet_parser.reduce_right(digit_parser, |lhs: i32, rhs: i32| -> i32 { rhs * 10 + lhs });
let res = rp::parse(&reduced_right, "123456dcba".chars());
assert_eq!(res.output.unwrap(), (3654321,));
assert_eq!(res.it.collect::<String>(), "cba");Sourcefn reduce_with<Init, Reducer>(
self,
init: Init,
reducer: Reducer,
) -> ReduceInitParser<Self::Into, Init, Reducer>
fn reduce_with<Init, Reducer>( self, init: Init, reducer: Reducer, ) -> ReduceInitParser<Self::Into, Init, Reducer>
Reduce the output of the parser with the given reducer.
With given input string self self self ... and the reducer f,
the output will be calculated as
f( f( f(init,self), self), self), ...
The signature of the reducer must be Fn(Init, A0, A1, A2, ...) -> Init.
Where (A0, A1, A2, ...) are the output of Self.
Output: Init
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser =
('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
let number_parser =
digit_parser.reduce_with(0, |acc, rhs| acc * 10 + rhs);
let res = rp::parse(&number_parser, "123456abc".chars());
assert_eq!(res.output.unwrap(), (123456,));
assert_eq!(res.it.collect::<String>(), "abc");Sourcefn reduce_right_with<Init, Reducer>(
self,
init: Init,
reducer: Reducer,
) -> ReduceRightInitParser<Self::Into, Init, Reducer>
fn reduce_right_with<Init, Reducer>( self, init: Init, reducer: Reducer, ) -> ReduceRightInitParser<Self::Into, Init, Reducer>
Reduce the output of the parser with the given reducer.
With given input string self self self ... and the reducer f,
the output will be calculated as
f(self, f(self, f(self, f( ... f(self,init)))
The signature of the reducer must be Fn(A0, A1, A2, ..., Init) -> Init.
Where (A0, A1, A2, ...) are the output of Self.
Output: Init
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser =
('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
let number_rev_parser =
digit_parser.reduce_right_with(0, |lhs, acc| acc * 10 + lhs);
let res = rp::parse(&number_rev_parser, "123456abc".chars());
assert_eq!(res.output.unwrap(), (654321,));
assert_eq!(res.it.collect::<String>(), "abc");Sourcefn inspect<ClosureType>(
self,
closure: ClosureType,
) -> InspectParser<Self::Into, ClosureType>
fn inspect<ClosureType>( self, closure: ClosureType, ) -> InspectParser<Self::Into, ClosureType>
This does what std::iter::Inspect do.
The closure will be called before parsing, regardless of the success or failure of the parser.
Output: Output of Self
§Example
use rusty_parser as rp;
use rp::IntoParser;
let digit_parser =
('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
let digit_parser = digit_parser.inspect(|| {
println!( "digit parser entered!" );
});
let res = rp::parse(&digit_parser, "123456abcd".chars());
assert_eq!(res.output.unwrap(), (1,));
assert_eq!(res.it.collect::<String>(), "23456abcd");