graphql_parser/
helpers.rs

1use std::marker::PhantomData;
2
3use combine::error::Tracked;
4use combine::stream::easy::{Error, Errors, Info};
5use combine::{satisfy, ParseResult, Parser, StreamOnce};
6
7use crate::position::Pos;
8use crate::tokenizer::{Kind, Token, TokenStream};
9
10use super::common::Text;
11
12#[derive(Debug, Clone)]
13pub struct TokenMatch<'a> {
14    kind: Kind,
15    phantom: PhantomData<&'a u8>,
16}
17
18#[derive(Debug, Clone)]
19pub struct NameMatch<'a, T>
20where
21    T: Text<'a>,
22{
23    phantom: PhantomData<&'a T>,
24}
25
26#[derive(Debug, Clone)]
27pub struct Value<'a> {
28    kind: Kind,
29    value: &'static str,
30    phantom: PhantomData<&'a u8>,
31}
32
33pub fn kind<'x>(kind: Kind) -> TokenMatch<'x> {
34    TokenMatch {
35        kind,
36        phantom: PhantomData,
37    }
38}
39
40pub fn name<'a, T>() -> NameMatch<'a, T>
41where
42    T: Text<'a>,
43{
44    NameMatch {
45        phantom: PhantomData,
46    }
47}
48
49impl<'a> Parser<TokenStream<'a>> for TokenMatch<'a> {
50    type Output = Token<'a>;
51    type PartialState = ();
52
53    #[inline]
54    fn parse_lazy(
55        &mut self,
56        input: &mut TokenStream<'a>,
57    ) -> ParseResult<Self::Output, <TokenStream<'a> as StreamOnce>::Error> {
58        satisfy(|c: Token<'a>| c.kind == self.kind).parse_lazy(input)
59    }
60
61    fn add_error(&mut self, error: &mut Tracked<Errors<Token<'a>, Token<'a>, Pos>>) {
62        error
63            .error
64            .add_error(Error::Expected(Info::Owned(format!("{:?}", self.kind))));
65    }
66}
67
68pub fn punct<'s>(value: &'static str) -> Value<'s> {
69    Value {
70        kind: Kind::Punctuator,
71        value,
72        phantom: PhantomData,
73    }
74}
75
76pub fn ident<'s>(value: &'static str) -> Value<'s> {
77    Value {
78        kind: Kind::Name,
79        value,
80        phantom: PhantomData,
81    }
82}
83
84impl<'a> Parser<TokenStream<'a>> for Value<'a> {
85    type Output = Token<'a>;
86    type PartialState = ();
87
88    #[inline]
89    fn parse_lazy(
90        &mut self,
91        input: &mut TokenStream<'a>,
92    ) -> ParseResult<Self::Output, <TokenStream<'a> as StreamOnce>::Error> {
93        satisfy(|c: Token<'a>| c.kind == self.kind && c.value == self.value).parse_lazy(input)
94    }
95
96    fn add_error(&mut self, error: &mut Tracked<<TokenStream<'a> as StreamOnce>::Error>) {
97        error
98            .error
99            .add_error(Error::Expected(Info::Static(self.value)));
100    }
101}
102
103impl<'a, S> Parser<TokenStream<'a>> for NameMatch<'a, S>
104where
105    S: Text<'a>,
106{
107    type Output = S::Value;
108    type PartialState = ();
109
110    #[inline]
111    fn parse_lazy(
112        &mut self,
113        input: &mut TokenStream<'a>,
114    ) -> ParseResult<Self::Output, <TokenStream<'a> as StreamOnce>::Error> {
115        satisfy(|c: Token<'a>| c.kind == Kind::Name)
116            .map(|t: Token<'a>| -> S::Value { S::Value::from(t.value) })
117            .parse_lazy(input)
118    }
119
120    fn add_error(&mut self, error: &mut Tracked<Errors<Token<'a>, Token<'a>, Pos>>) {
121        error.error.add_error(Error::Expected(Info::Static("Name")));
122    }
123}