rusty_parser/core/
into_parser.rs

1pub trait IntoParser {
2    /// Target Parser type
3    type Into;
4
5    /// convert self to Parser
6    ///
7    /// # Example
8    /// ```rust
9    /// use rusty_parser as rp;
10    /// use rp::IntoParser;
11    ///
12    /// let hello_parser = "hello".into_parser();
13    /// let a_parser = 'a'.into_parser();
14    /// let digit_parser = ('0'..='9').into_parser();
15    /// ```
16    fn into_parser(self) -> Self::Into;
17
18    /// concatenate two parser
19    ///
20    /// `Output`: `( A0, A1, ..., B0, B1, ..., C0, C1, ... )`
21    /// where `(A0, A1, ...)` are the output of the first parser,
22    /// and `(B0, B1, ...)`, `(C0, C1, ...)` are the output of the following parsers.
23    ///
24    /// # Example
25    /// ```rust
26    /// use rusty_parser as rp;
27    /// use rp::IntoParser;
28    ///
29    /// // 'a', and then 'b'
30    /// let ab_parser = rp::seq!('a', 'b', 'c'); // IntoParser for char
31    ///
32    /// let res = rp::parse(&ab_parser, "abcd".chars());
33    /// assert_eq!(res.output.unwrap(), ('a', 'b', 'c')); // Output is concatenated
34    /// assert_eq!(res.it.collect::<String>(), "d");
35    /// ```
36    fn seq<RhsParser: IntoParser>(
37        self,
38        rhs: RhsParser,
39    ) -> crate::wrapper::seq::SeqParser<Self::Into, RhsParser::Into>
40    where
41        Self: Sized,
42    {
43        crate::wrapper::seq::SeqParser::new(self.into_parser(), rhs.into_parser())
44    }
45
46    /// repeat parser multiple times. This tries to match as long as possible.
47    ///
48    /// `Output`:
49    ///  - if `Output` of the repeated parser is `()`, then `Output` is `()`
50    ///  - if `Output` of the repeated parser is `(T,)`, then `Output` is `(Vec<T>,)`
51    ///  - otherwise, `(Vec<Output of Self>,)`
52    ///
53    /// # Example
54    /// ```rust
55    /// use rusty_parser as rp;
56    /// use rp::IntoParser;
57    ///
58    /// // repeat 'a' 3 to 5 times
59    /// let multiple_a_parser = 'a'.repeat(3..=5);
60    /// let res = rp::parse(&multiple_a_parser, "aaaabcd".chars());
61    /// // four 'a' is parsed
62    /// assert_eq!(res.output.unwrap(), (vec!['a', 'a', 'a', 'a',],));
63    /// assert_eq!(res.it.collect::<String>(), "bcd");
64    ///
65    /// let multiple_a_parser = 'a'.repeat(3usize);
66    /// let res = rp::parse(&multiple_a_parser, "aaaabcd".chars());
67    /// // three 'a' is parsed
68    /// assert_eq!(res.output.unwrap(), (vec!['a', 'a', 'a'],));
69    /// ```
70    fn repeat<RangeTypeIncludeInteger>(
71        self,
72        range: RangeTypeIncludeInteger,
73    ) -> crate::wrapper::repeat::RepeatParser<Self::Into, RangeTypeIncludeInteger::Into>
74    where
75        Self: Sized,
76        RangeTypeIncludeInteger: crate::core::range_copyable::ToCopyable,
77        RangeTypeIncludeInteger::Into:
78            crate::core::range_copyable::RangeBound<crate::wrapper::repeat::RepeatCountType>,
79    {
80        crate::wrapper::repeat::RepeatParser::from(self.into_parser(), range)
81    }
82
83    /// or combinator for two parsers
84    ///
85    /// `Output`: `Output` of the all parsers.
86    /// Note that the output of all parsers must be the same type.
87    ///
88    /// # Example
89    /// ```rust
90    /// use rusty_parser as rp;
91    /// use rp::IntoParser;
92    ///
93    /// // 'a' or 'b'
94    /// let ab_parser = rp::or!('a', 'b'); // IntoParser for char
95    ///
96    /// // 'a' is matched
97    /// let res = rp::parse(&ab_parser, "abcd".chars());
98    /// assert_eq!(res.output.unwrap(), ('a',)); // Output of 'a'
99    /// assert_eq!(res.it.clone().collect::<String>(), "bcd");
100    ///
101    /// // continue parsing from the rest
102    /// // 'a' is not matched, but 'b' is matched
103    /// let res = rp::parse(&ab_parser, res.it);
104    /// assert_eq!(res.output.unwrap(), ('b',));
105    /// assert_eq!(res.it.clone().collect::<String>(), "cd");
106    ///
107    /// // continue parsing from the rest
108    /// // 'a' is not matched, 'b' is not matched; failed
109    /// let res = rp::parse(&ab_parser, res.it);
110    /// assert_eq!(res.output, None);
111    /// assert_eq!(res.it.clone().collect::<String>(), "cd");
112    /// ```
113    fn or<RhsParser: IntoParser>(
114        self,
115        rhs: RhsParser,
116    ) -> crate::wrapper::or::OrParser<Self::Into, RhsParser::Into>
117    where
118        Self: Sized,
119    {
120        crate::wrapper::or::OrParser::new(self.into_parser(), rhs.into_parser())
121    }
122
123    /// Map parser's Output to new value.
124    ///
125    /// Parser's Output will be unpacked and passed to the closure. The value returned from the closure will be new Output.
126    ///
127    /// `Output`: `(T,)` where `T` is return type of the closure.
128    /// The value `v` returned from the closure will be wrapped into `(v,)`.
129    ///
130    /// # Example
131    /// ```rust
132    /// use rusty_parser as rp;
133    /// use rp::IntoParser;
134    ///
135    /// // map the output
136    /// // <Output of 'a'> -> i32
137    /// let int_parser = 'a'.map(|ch| -> i32 { ch as i32 - 'a' as i32 });
138    ///
139    /// let res = rp::parse(&int_parser, "abcd".chars());
140    /// assert_eq!(res.output.unwrap(), (0,));
141    /// assert_eq!(res.it.collect::<String>(), "bcd");
142    /// ```
143    fn map<ClosureType>(
144        self,
145        callback: ClosureType,
146    ) -> crate::wrapper::map::MapParser<Self::Into, ClosureType>
147    where
148        Self: Sized,
149    {
150        crate::wrapper::map::MapParser::new(self.into_parser(), callback)
151    }
152
153    /// Change Parser's Output to `()`.
154    /// This internally call `crate::match_pattern()` instead of `crate::parse()`
155    ///
156    /// `Output`: `()`
157    ///
158    /// # Example
159    /// ```rust
160    /// use rusty_parser as rp;
161    /// use rp::IntoParser;
162    ///
163    /// let expensive_parser = 'a'.map(|_| -> i32 {
164    ///     // some expensive operations for data extracting...
165    ///     panic!("This should not be called");
166    /// });
167    /// let expensive_parser = expensive_parser.void();
168    ///
169    /// // ignore the output of parser
170    /// // this internally calls 'match_pattern(...)' instead of 'parse(...)'
171    /// let res = rp::parse(&expensive_parser, "abcd".chars());
172    /// assert_eq!(res.output.unwrap(), ());
173    /// assert_eq!(res.it.collect::<String>(), "bcd");
174    /// ```
175    fn void(self) -> crate::wrapper::void::VoidParser<Self::Into>
176    where
177        Self: Sized,
178    {
179        crate::wrapper::void::VoidParser::new(self.into_parser())
180    }
181
182    /// This parser always success whether the input is matched or not.
183    ///
184    /// `Output`:
185    ///  - if `Output` of the origin parser is `(T0,)`, `(Option<T0>,)`
186    ///  - otherwise, `( Option<Output of Self>, )`
187    ///
188    /// # Example
189    /// ```rust
190    /// use rusty_parser as rp;
191    /// use rp::IntoParser;
192    ///
193    /// let a_optional_parser = 'a'.optional(); // (Option<char>,)
194    ///
195    /// let res = rp::parse(&a_optional_parser, "abcd".chars()); // success
196    /// assert_eq!(res.output.unwrap(), (Some('a'),));
197    ///
198    /// let res = rp::parse(&a_optional_parser, "bcd".chars()); // success, but 'a' is not matched
199    /// assert_eq!(res.output.unwrap(), (None,));
200    /// ```
201    fn optional(self) -> crate::wrapper::option::OptionalParser<Self::Into>
202    where
203        Self: Sized,
204    {
205        crate::wrapper::option::OptionalParser::new(self.into_parser())
206    }
207
208    /// This parser always success whether the input is matched or not.
209    /// If it failed, the given value will be returned.
210    ///
211    /// `Output`:
212    /// <`Output` of Self>.
213    ///
214    /// The value given to `optional_or` must match with the `Output` of the origin parser.
215    ///
216    /// For single-value-output ( which's output is `(T,)` ),
217    /// passing either `T` or `(T,)` is permitted.
218    ///
219    /// # Example
220    /// ```rust
221    /// use rusty_parser as rp;
222    /// use rp::IntoParser;
223    ///
224    /// // if 'a' failed, return 'x'
225    /// let a_optional_or = 'a'.optional_or('x'); // (char,)
226    ///
227    /// let res = rp::parse(&a_optional_or, "bcd".chars());
228    /// assert_eq!(res.output.unwrap(), ('x',));
229    /// ```
230    fn optional_or<Output: Clone>(
231        self,
232        output: Output,
233    ) -> crate::wrapper::option::OptionalOrParser<Self::Into, Output>
234    where
235        Self: Sized,
236    {
237        crate::wrapper::option::OptionalOrParser::new(self.into_parser(), output)
238    }
239
240    /// This parser always success whether the input is matched or not.
241    /// If it failed, the given closure will be evaluated and returned.
242    ///
243    /// `Output`:
244    /// <`Output` of Self>.
245    ///
246    /// The value given to `or_else` must match with the `Output` of the origin parser.
247    ///
248    /// For single-value-output ( which's output is `(T,)` ),
249    /// returning either `T` or `(T,)` is permitted.
250    ///
251    /// # Example
252    /// ```rust
253    /// use rusty_parser as rp;
254    /// use rp::IntoParser;
255    ///
256    /// // if 'a' failed, return 'x'
257    /// let a_or_else = 'a'.or_else(|| 'x'); // (char,)
258    ///
259    /// let res = rp::parse(&a_or_else, "bcd".chars());
260    /// assert_eq!(res.output.unwrap(), ('x',));
261    /// ```
262    fn or_else<Closure>(
263        self,
264        closure: Closure,
265    ) -> crate::wrapper::or_else::OptionalOrElseParser<Self::Into, Closure>
266    where
267        Self: Sized,
268    {
269        crate::wrapper::or_else::OptionalOrElseParser::new(self.into_parser(), closure)
270    }
271
272    /// Match for parser1 but not parser2.
273    ///
274    /// `Output`: `Output` of `Self`
275    ///
276    /// # Example
277    /// ```rust
278    /// use rusty_parser as rp;
279    /// use rp::IntoParser;
280    ///
281    /// let digit_parser_except_4 = ('0'..='9').not('4');
282    ///
283    /// let res = rp::parse(&digit_parser_except_4, "3".chars());
284    /// assert_eq!(res.output.unwrap(), ('3',));
285    ///
286    /// let res = rp::parse(&digit_parser_except_4, "4".chars());
287    /// assert_eq!(res.output, None);
288    /// ```
289    fn not<RhsParser: IntoParser>(
290        self,
291        rhs: RhsParser,
292    ) -> crate::wrapper::not::NotParser<Self::Into, RhsParser::Into>
293    where
294        Self: Sized,
295    {
296        crate::wrapper::not::NotParser::new(self.into_parser(), rhs.into_parser())
297    }
298
299    /// Change Parser's Output to (output,).
300    ///
301    /// `Output`: `(T,)` where `T` is the type of the value you provided.
302    ///
303    /// # Example
304    /// ```rust
305    /// use rusty_parser as rp;
306    /// use rp::IntoParser;
307    ///
308    /// let digit_parser = ('0'..='9').output(2024);
309    ///
310    /// let res = rp::parse(&digit_parser, "123456hello_world".chars());
311    /// assert_eq!(res.output.unwrap(), (2024,));
312    /// assert_eq!(res.it.collect::<String>(), "23456hello_world");
313    /// ```
314    fn output<Output: Clone>(
315        self,
316        output: Output,
317    ) -> crate::wrapper::output::OutputParser<Self::Into, Output>
318    where
319        Self: Sized,
320    {
321        crate::wrapper::output::OutputParser::new(self.into_parser(), output)
322    }
323
324    /// Returns String of parsed input.
325    /// Only works for parsing with [`std::str::Chars`].
326    ///
327    /// `Output`: `(String,)`
328    ///
329    ///
330    /// # Example
331    /// ```rust
332    /// use rusty_parser as rp;
333    /// use rp::IntoParser;
334    ///
335    /// let digits_parser = ('0'..='9').repeat(0..).string();
336    ///
337    /// let res = rp::parse(&digits_parser, "123456hello_world".chars());
338    /// assert_eq!(res.output.unwrap(), ("123456".to_string(),));
339    /// assert_eq!(res.it.collect::<String>(), "hello_world");
340    /// ```
341    fn string(self) -> crate::wrapper::slice::StringParser<Self::Into>
342    where
343        Self: Sized,
344        Self::Into: for<'a> crate::core::parser::Parser<std::str::Chars<'a>>,
345    {
346        crate::wrapper::slice::StringParser::new(self.into_parser())
347    }
348
349    /// Returns `Vec\<T\>` of parsed input.
350    /// Only works for parsing with [`ExactSizeIterator`].
351    ///
352    /// `Output`: `(Vec<Iterator::Item>,)`
353    ///
354    /// # Example
355    /// ```rust
356    /// use rusty_parser as rp;
357    /// use rp::IntoParser;
358    ///
359    /// let hello_bytes = &[104, 101, 108, 108, 111];
360    /// let hello_parser = hello_bytes.into_parser().vec::<u8>();
361    ///
362    /// let res = rp::parse(&hello_parser, "hello_world1234".as_bytes().iter().copied());
363    /// assert_eq!(res.output.unwrap(), (hello_bytes.iter().cloned().collect::<Vec<u8>>(),) );
364    /// ```
365    fn vec<T>(self) -> crate::wrapper::slice::VecParser<Self::Into>
366    where
367        Self: Sized,
368        Self::Into: for<'a> crate::core::parser::Parser<std::iter::Cloned<std::slice::Iter<'a, T>>>,
369    {
370        crate::wrapper::slice::VecParser::new(self.into_parser())
371    }
372
373    /// Parser will not consume the input iterator.
374    /// It still matches and return the output.
375    ///
376    /// # Example
377    /// ```rust
378    /// use rusty_parser as rp;
379    /// use rp::IntoParser;
380    ///
381    /// let digit_parser = ('0'..='9').not_consume();
382    ///
383    /// let res = rp::parse(&digit_parser, "12345".chars());
384    /// assert_eq!(res.output.unwrap(), ('1',));
385    /// assert_eq!(res.it.collect::<String>(), "12345"); // iterator is not consumed
386    /// ```
387    fn not_consume(self) -> crate::wrapper::notconsume::NotConsumeParser<Self::Into>
388    where
389        Self: Sized,
390    {
391        crate::wrapper::notconsume::NotConsumeParser::new(self.into_parser())
392    }
393
394    /// Reduce the output of the parser with the given reducer.
395    ///
396    /// With given input string `self rhs rhs rhs rhs ...` and the reducer `f`,
397    /// the output will be calculated as
398    /// `f( f( f(self,rhs), rhs ), rhs ), ...`
399    ///
400    /// ## Note
401    ///
402    ///  - The signature of the reducer must be `Fn(A0, A1, A2, ..., B0, B1, B2, ...) -> ( A0, A1, A2 ... )`.
403    ///    Where `(A0, A1, A2, ...)` are the output of the first parser, and `(B0, B1, B2, ...)` are the output of the following parser.
404    ///
405    ///  - For single-value-output ( which's output is `(T,)` ),
406    ///    returning either `T` or `(T,)` is permitted.
407    ///
408    /// `Output`: `Output` of `Self`
409    ///
410    /// # Example
411    /// ```rust
412    /// use rusty_parser as rp;
413    /// use rp::IntoParser;
414    ///
415    /// let digit_parser = ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
416    /// let reduced_left = digit_parser.reduce_left(digit_parser, |lhs, rhs| lhs * 10 + rhs);
417    /// let res = rp::parse( &reduced_left, "123456abcd".chars() );
418    /// assert_eq!(res.output.unwrap(), (123456,));
419    /// ```
420    fn reduce_left<RhsParser, Reducer>(
421        self,
422        rhs: RhsParser,
423        reducer: Reducer,
424    ) -> crate::wrapper::reduce::left::ReduceLeftParser<Self::Into, RhsParser::Into, Reducer>
425    where
426        Self: Sized,
427        RhsParser: IntoParser,
428    {
429        crate::wrapper::reduce::left::ReduceLeftParser::new(
430            self.into_parser(),
431            rhs.into_parser(),
432            reducer,
433        )
434    }
435
436    /// Reduce the output of the parser with the given reducer.
437    ///
438    /// With given input string `lhs lhs lhs lhs ... self` and the reducer `f`,
439    /// the output will be calculated as
440    /// `f(lhs, f(lhs, f(lhs, f( ... f(lhs,self)))`
441    ///
442    /// ## Note
443    ///
444    ///  - The signature of the reducer must be `Fn(A0, A1, A2, ..., B0, B1, B2, ...) -> ( B0, B1, B2 ... )`.
445    ///    Where `(A0, A1, A2, ...)` are the output of the first parser, and `(B0, B1, B2, ...)` are the output of the following parser.
446    ///
447    ///  - For single-value-output ( which's output is `(T,)` ),
448    ///    returning either `T` or `(T,)` is permitted.
449    ///
450    /// `Output`: `Output` of `Self`
451    ///
452    /// # Example
453    /// ```rust
454    /// use rusty_parser as rp;
455    /// use rp::IntoParser;
456    ///
457    /// let digit_parser =
458    ///     ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
459    /// let alphabet_parser =
460    ///     ('a'..='z').into_parser().map(|val: char| -> i32 { val as i32 - 'a' as i32 });
461    /// let reduced_right =
462    ///     alphabet_parser.reduce_right(digit_parser, |lhs: i32, rhs: i32| -> i32 { rhs * 10 + lhs });
463    ///
464    /// let res = rp::parse(&reduced_right, "123456dcba".chars());
465    /// assert_eq!(res.output.unwrap(), (3654321,));
466    /// assert_eq!(res.it.collect::<String>(), "cba");
467    /// ```
468    fn reduce_right<LhsParser, Reducer>(
469        self,
470        lhs: LhsParser,
471        reducer: Reducer,
472    ) -> crate::wrapper::reduce::right::ReduceRightParser<LhsParser::Into, Self::Into, Reducer>
473    where
474        Self: Sized,
475        LhsParser: IntoParser,
476    {
477        crate::wrapper::reduce::right::ReduceRightParser::new(
478            lhs.into_parser(),
479            self.into_parser(),
480            reducer,
481        )
482    }
483
484    /// Reduce the output of the parser with the given reducer.
485    ///
486    /// With given input string `self self self ...` and the reducer `f`,
487    /// the output will be calculated as
488    /// `f( f( f(init,self), self), self), ...`
489    ///
490    /// The signature of the reducer must be `Fn(Init, A0, A1, A2, ...) -> Init`.
491    /// Where `(A0, A1, A2, ...)` are the output of `Self`.
492    ///
493    /// `Output`: `Init`
494    ///
495    /// # Example
496    /// ```rust
497    /// use rusty_parser as rp;
498    /// use rp::IntoParser;
499    ///
500    /// let digit_parser =
501    ///     ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
502    /// let number_parser =
503    ///     digit_parser.reduce_with(0, |acc, rhs| acc * 10 + rhs);
504    ///
505    /// let res = rp::parse(&number_parser, "123456abc".chars());
506    /// assert_eq!(res.output.unwrap(), (123456,));
507    /// assert_eq!(res.it.collect::<String>(), "abc");
508    /// ```
509    fn reduce_with<Init, Reducer>(
510        self,
511        init: Init,
512        reducer: Reducer,
513    ) -> crate::wrapper::reduce::init::ReduceInitParser<Self::Into, Init, Reducer>
514    where
515        Self: Sized,
516        Init: Clone,
517    {
518        crate::wrapper::reduce::init::ReduceInitParser::new(self.into_parser(), init, reducer)
519    }
520
521    /// Reduce the output of the parser with the given reducer.
522    ///
523    /// With given input string `self self self ...` and the reducer `f`,
524    /// the output will be calculated as
525    /// `f(self, f(self, f(self, f( ... f(self,init)))`
526    ///
527    /// The signature of the reducer must be `Fn(A0, A1, A2, ..., Init) -> Init`.
528    /// Where `(A0, A1, A2, ...)` are the output of `Self`.
529    ///
530    /// `Output`: `Init`
531    ///
532    /// # Example
533    /// ```rust
534    /// use rusty_parser as rp;
535    /// use rp::IntoParser;
536    ///
537    /// let digit_parser =
538    ///     ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
539    /// let number_rev_parser =
540    ///     digit_parser.reduce_right_with(0, |lhs, acc| acc * 10 + lhs);
541    ///
542    /// let res = rp::parse(&number_rev_parser, "123456abc".chars());
543    /// assert_eq!(res.output.unwrap(), (654321,));
544    /// assert_eq!(res.it.collect::<String>(), "abc");
545    /// ```
546    fn reduce_right_with<Init, Reducer>(
547        self,
548        init: Init,
549        reducer: Reducer,
550    ) -> crate::wrapper::reduce::init_right::ReduceRightInitParser<Self::Into, Init, Reducer>
551    where
552        Self: Sized,
553        Init: Clone,
554    {
555        crate::wrapper::reduce::init_right::ReduceRightInitParser::new(
556            self.into_parser(),
557            init,
558            reducer,
559        )
560    }
561
562    /// This does what [`std::iter::Inspect`] do.
563    /// The closure will be called before parsing, regardless of the success or failure of the parser.
564    ///
565    /// `Output`: `Output` of `Self`
566    ///
567    /// # Example
568    /// ```rust
569    /// use rusty_parser as rp;
570    /// use rp::IntoParser;
571    ///
572    /// let digit_parser =
573    ///     ('0'..='9').into_parser().map(|val: char| -> i32 { val as i32 - '0' as i32 });
574    /// let digit_parser = digit_parser.inspect(|| {
575    ///   println!( "digit parser entered!" );
576    /// });
577    ///
578    /// let res = rp::parse(&digit_parser, "123456abcd".chars());
579    /// assert_eq!(res.output.unwrap(), (1,));
580    /// assert_eq!(res.it.collect::<String>(), "23456abcd");
581    fn inspect<ClosureType>(
582        self,
583        closure: ClosureType,
584    ) -> crate::wrapper::inspect::InspectParser<Self::Into, ClosureType>
585    where
586        Self: Sized,
587        ClosureType: Fn(),
588    {
589        crate::wrapper::inspect::InspectParser::new(self.into_parser(), closure)
590    }
591}