1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::ast::executable::{SelectionSet, VariableDefinitions};
use crate::ast::{
FromTokens, IsMatch, OperationType, ParseError, Tokens, TryFromTokens, VariableDirectives,
};
use crate::lexical_token::Name;
pub type OperationDefinition<'a> = bluejay_core::executable::OperationDefinition<
ExplicitOperationDefinition<'a>,
ImplicitOperationDefinition<'a>,
>;
impl<'a> FromTokens<'a> for OperationDefinition<'a> {
fn from_tokens(tokens: &mut impl Tokens<'a>) -> Result<Self, ParseError> {
if let Some(operation_type) = OperationType::try_from_tokens(tokens).transpose()? {
let name = tokens.next_if_name();
let variable_definitions = VariableDefinitions::try_from_tokens(tokens).transpose()?;
let directives = VariableDirectives::from_tokens(tokens)?;
let selection_set = SelectionSet::from_tokens(tokens)?;
Ok(Self::Explicit(ExplicitOperationDefinition {
operation_type,
name,
variable_definitions,
directives,
selection_set,
}))
} else if let Some(selection_set) = SelectionSet::try_from_tokens(tokens).transpose()? {
Ok(Self::Implicit(ImplicitOperationDefinition {
selection_set,
}))
} else {
Err(tokens.unexpected_token())
}
}
}
impl<'a> IsMatch<'a> for OperationDefinition<'a> {
fn is_match(tokens: &mut impl Tokens<'a>) -> bool {
OperationType::is_match(tokens) || SelectionSet::is_match(tokens)
}
}
#[derive(Debug)]
pub struct ExplicitOperationDefinition<'a> {
operation_type: OperationType,
name: Option<Name<'a>>,
variable_definitions: Option<VariableDefinitions<'a>>,
directives: VariableDirectives<'a>,
selection_set: SelectionSet<'a>,
}
impl<'a> bluejay_core::executable::ExplicitOperationDefinition for ExplicitOperationDefinition<'a> {
type VariableDefinitions = VariableDefinitions<'a>;
type Directives = VariableDirectives<'a>;
type SelectionSet = SelectionSet<'a>;
fn operation_type(&self) -> bluejay_core::OperationType {
(&self.operation_type).into()
}
fn name(&self) -> Option<&str> {
self.name.as_ref().map(|name| name.as_ref())
}
fn variable_definitions(&self) -> Option<&Self::VariableDefinitions> {
self.variable_definitions.as_ref()
}
fn directives(&self) -> &Self::Directives {
&self.directives
}
fn selection_set(&self) -> &Self::SelectionSet {
&self.selection_set
}
}
impl<'a> ExplicitOperationDefinition<'a> {
pub fn name(&self) -> Option<&Name<'a>> {
self.name.as_ref()
}
pub fn operation_type(&self) -> &OperationType {
&self.operation_type
}
}
#[derive(Debug)]
pub struct ImplicitOperationDefinition<'a> {
selection_set: SelectionSet<'a>,
}
impl<'a> bluejay_core::executable::ImplicitOperationDefinition for ImplicitOperationDefinition<'a> {
type SelectionSet = SelectionSet<'a>;
fn selection_set(&self) -> &Self::SelectionSet {
&self.selection_set
}
}