Skip to main content

oni_comb_parser/combinator/
fn_parser.rs

1use crate::fail::PResult;
2use crate::input::Input;
3use crate::parser::Parser;
4
5/// 関数ポインタを `Parser` としてラップする。
6///
7/// `recursive()` の `Box<dyn Parser>` + vtable を回避し、
8/// 通常の関数呼び出しで再帰パーサーを構築できる。
9///
10/// ```ignore
11/// fn my_value<'a>(input: &mut StrInput<'a>) -> PResult<Json, ParseError> {
12///     // 先頭バイトで分岐 → 各コンビネータを呼ぶ
13///     // 再帰は fn_parser(my_value) で自分自身を参照
14/// }
15/// let parser = fn_parser(my_value);
16/// ```
17pub struct FnParser<F> {
18  f: F,
19}
20
21pub fn fn_parser<I, O, E, F>(f: F) -> FnParser<F>
22where
23  I: Input,
24  F: FnMut(&mut I) -> PResult<O, E>, {
25  FnParser { f }
26}
27
28impl<I, O, E, F> Parser<I> for FnParser<F>
29where
30  I: Input,
31  F: FnMut(&mut I) -> PResult<O, E>,
32{
33  type Error = E;
34  type Output = O;
35
36  #[inline]
37  fn parse_next(&mut self, input: &mut I) -> PResult<O, E> {
38    (self.f)(input)
39  }
40}