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}