cynic_parser/executable/
writer.rs

1use std::sync::Arc;
2
3use indexmap::IndexSet;
4
5use crate::common::IdRange;
6
7use super::{ids::*, storage::*, ExecutableDocument};
8
9pub struct ExecutableAstWriter {
10    pub values: crate::values::writer::ValueWriter,
11
12    strings: IndexSet<Box<str>>,
13    block_strings: Vec<Box<str>>,
14
15    definitions: Vec<ExecutableDefinitionRecord>,
16    operations: Vec<OperationDefinitionRecord>,
17    fragments: Vec<FragmentDefinitionRecord>,
18
19    selections: Vec<SelectionRecord>,
20    field_selections: Vec<FieldSelectionRecord>,
21    inline_fragments: Vec<InlineFragmentRecord>,
22    fragment_spreads: Vec<FragmentSpreadRecord>,
23
24    directives: Vec<DirectiveRecord>,
25    arguments: Vec<ArgumentRecord>,
26    variables: Vec<VariableDefinitionRecord>,
27
28    types: Vec<TypeRecord>,
29
30    directive_cursor: DirectiveId,
31    variable_definition_cursor: VariableDefinitionId,
32}
33
34impl Default for ExecutableAstWriter {
35    fn default() -> Self {
36        Self {
37            strings: Default::default(),
38            block_strings: Default::default(),
39            definitions: Default::default(),
40            operations: Default::default(),
41            fragments: Default::default(),
42            selections: Default::default(),
43            field_selections: Default::default(),
44            inline_fragments: Default::default(),
45            fragment_spreads: Default::default(),
46            directives: Default::default(),
47            arguments: Default::default(),
48            variables: Default::default(),
49            types: Default::default(),
50            values: Default::default(),
51            directive_cursor: DirectiveId::new(0),
52            variable_definition_cursor: VariableDefinitionId::new(0),
53        }
54    }
55}
56
57impl ExecutableAstWriter {
58    pub fn new() -> Self {
59        Self::default()
60    }
61
62    pub fn finish(self) -> ExecutableDocument {
63        // TODO: Possibly assert things in here for safety...
64        let ExecutableAstWriter {
65            strings,
66            block_strings,
67            definitions,
68            operations,
69            fragments,
70            selections,
71            field_selections,
72            inline_fragments,
73            fragment_spreads,
74            directives,
75            arguments,
76            variables,
77            types,
78            values,
79            directive_cursor: _,
80            variable_definition_cursor: _,
81        } = self;
82
83        let strings = Arc::new(strings);
84        let values = values.finish(Arc::clone(&strings));
85
86        ExecutableDocument {
87            strings,
88            block_strings,
89            definitions,
90            operations,
91            fragments,
92            selections,
93            field_selections,
94            inline_fragments,
95            fragment_spreads,
96            directives,
97            arguments,
98            variables,
99            types,
100            values,
101        }
102    }
103
104    pub fn operation_definition(
105        &mut self,
106        definition: OperationDefinitionRecord,
107    ) -> ExecutableDefinitionId {
108        let id = OperationDefinitionId::new(self.operations.len());
109        self.operations.push(definition);
110
111        let definition_id = ExecutableDefinitionId::new(self.definitions.len());
112        self.definitions
113            .push(ExecutableDefinitionRecord::Operation(id));
114
115        definition_id
116    }
117
118    pub fn fragment_definition(
119        &mut self,
120        definition: FragmentDefinitionRecord,
121    ) -> ExecutableDefinitionId {
122        let id = FragmentDefinitionId::new(self.fragments.len());
123        self.fragments.push(definition);
124
125        let definition_id = ExecutableDefinitionId::new(self.definitions.len());
126        self.definitions
127            .push(ExecutableDefinitionRecord::Fragment(id));
128
129        definition_id
130    }
131
132    pub fn variable_definition(
133        &mut self,
134        record: VariableDefinitionRecord,
135    ) -> VariableDefinitionId {
136        let id = VariableDefinitionId::new(self.variables.len());
137        self.variables.push(record);
138        id
139    }
140
141    pub fn variable_definition_range(
142        &mut self,
143        expected_count: Option<usize>,
144    ) -> IdRange<VariableDefinitionId> {
145        let start = self.variable_definition_cursor;
146        let end = VariableDefinitionId::new(self.variables.len());
147        self.variable_definition_cursor = end;
148        let range = IdRange::new(start, end);
149
150        assert_eq!(range.len(), expected_count.unwrap_or_default());
151
152        range
153    }
154
155    pub fn type_reference(&mut self, ty: TypeRecord) -> TypeId {
156        let ty_id = TypeId::new(self.types.len());
157        self.types.push(ty);
158        ty_id
159    }
160
161    pub fn selection_set(
162        &mut self,
163        mut selection_set: Vec<SelectionRecord>,
164    ) -> IdRange<SelectionId> {
165        let start_range = SelectionId::new(self.selections.len());
166        self.selections.append(&mut selection_set);
167        let end_range = SelectionId::new(self.selections.len());
168
169        IdRange::new(start_range, end_range)
170    }
171
172    pub fn field_selection(&mut self, record: FieldSelectionRecord) -> FieldSelectionId {
173        let id = FieldSelectionId::new(self.field_selections.len());
174        self.field_selections.push(record);
175        id
176    }
177
178    pub fn fragment_spread(&mut self, record: FragmentSpreadRecord) -> FragmentSpreadId {
179        let id = FragmentSpreadId::new(self.fragment_spreads.len());
180        self.fragment_spreads.push(record);
181        id
182    }
183
184    pub fn inline_fragment(&mut self, record: InlineFragmentRecord) -> InlineFragmentId {
185        let id = InlineFragmentId::new(self.inline_fragments.len());
186        self.inline_fragments.push(record);
187        id
188    }
189
190    pub fn arguments(&mut self, mut records: Vec<ArgumentRecord>) -> IdRange<ArgumentId> {
191        let start = ArgumentId::new(self.arguments.len());
192        self.arguments.append(&mut records);
193        let end = ArgumentId::new(self.arguments.len());
194
195        IdRange::new(start, end)
196    }
197
198    pub fn directive(&mut self, directive: DirectiveRecord) -> DirectiveId {
199        let id = DirectiveId::new(self.directives.len());
200        self.directives.push(directive);
201        id
202    }
203
204    pub fn directive_range(&mut self, expected_count: Option<usize>) -> IdRange<DirectiveId> {
205        let start = self.directive_cursor;
206        let end = DirectiveId::new(self.directives.len());
207        self.directive_cursor = end;
208        let range = IdRange::new(start, end);
209
210        assert_eq!(range.len(), expected_count.unwrap_or_default());
211
212        range
213    }
214
215    pub fn block_string(&mut self, string: &str) -> BlockStringLiteralId {
216        let literal_id = BlockStringLiteralId::new(self.block_strings.len());
217        self.block_strings.push(string.into());
218
219        literal_id
220    }
221
222    pub fn ident(&mut self, ident: &str) -> StringId {
223        self.intern_string(ident)
224    }
225
226    // TOOD: should this be pub? not sure...
227    pub fn intern_string(&mut self, string: &str) -> StringId {
228        let (id, _) = self.strings.insert_full(string.into());
229        StringId::new(id)
230    }
231
232    // TOOD: should this be pub? not sure...
233    pub fn intern_owned_string(&mut self, string: String) -> StringId {
234        let (id, _) = self.strings.insert_full(string.into());
235        StringId::new(id)
236    }
237}