1use std::{str::FromStr, sync::Arc};
2
3use indexmap::IndexSet;
4
5pub mod ids;
6pub mod iter;
7pub mod writer;
8
9mod definitions;
10mod extensions;
11mod generated;
12mod schemas;
13mod string_literal;
14mod types;
15mod values;
16use crate::common::IdRange;
19
20pub use self::{
21 definitions::{Definition, TypeDefinition},
22 generated::{
23 arguments::Argument,
24 descriptions::Description,
25 directives::{Directive, DirectiveDefinition},
26 enums::{EnumDefinition, EnumValueDefinition},
27 fields::FieldDefinition,
28 input_objects::InputObjectDefinition,
29 input_values::InputValueDefinition,
30 interfaces::InterfaceDefinition,
31 objects::ObjectDefinition,
32 scalars::ScalarDefinition,
33 schemas::{RootOperationTypeDefinition, SchemaDefinition},
34 unions::{UnionDefinition, UnionMember},
35 },
36 iter::Iter,
37 string_literal::{StringLiteral, StringLiteralKind},
38 types::{NamedTypeDefinition, NamedTypeDefinitions, Type},
39};
40use self::{ids::*, storage::DefinitionRecord};
41
42#[derive(Default)]
43pub struct TypeSystemDocument {
44 strings: Arc<IndexSet<Box<str>>>,
45 block_strings: Vec<Box<str>>,
46
47 definitions: Vec<storage::DefinitionRecord>,
48
49 schema_definitions: Vec<storage::SchemaDefinitionRecord>,
50 scalar_definitions: Vec<storage::ScalarDefinitionRecord>,
51 object_definitions: Vec<storage::ObjectDefinitionRecord>,
52 interface_definitions: Vec<storage::InterfaceDefinitionRecord>,
53 union_definitions: Vec<storage::UnionDefinitionRecord>,
54 enum_definitions: Vec<storage::EnumDefinitionRecord>,
55 input_object_definitions: Vec<storage::InputObjectDefinitionRecord>,
56 directive_definitions: Vec<storage::DirectiveDefinitionRecord>,
57
58 root_operation_definitions: Vec<storage::RootOperationTypeDefinitionRecord>,
59
60 field_definitions: Vec<storage::FieldDefinitionRecord>,
61 input_value_definitions: Vec<storage::InputValueDefinitionRecord>,
62 enum_value_definitions: Vec<storage::EnumValueDefinitionRecord>,
63 union_members: Vec<storage::UnionMemberRecord>,
64
65 type_references: Vec<storage::TypeRecord>,
66
67 directives: Vec<storage::DirectiveRecord>,
68 arguments: Vec<storage::ArgumentRecord>,
69 descriptions: Vec<storage::DescriptionRecord>,
70
71 values: crate::values::ValueStore,
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
75pub enum DirectiveLocation {
76 Query,
77 Mutation,
78 Subscription,
79 Field,
80 FragmentDefinition,
81 FragmentSpread,
82 InlineFragment,
83 Schema,
84 Scalar,
85 Object,
86 FieldDefinition,
87 ArgumentDefinition,
88 Interface,
89 Union,
90 Enum,
91 EnumValue,
92 InputObject,
93 InputFieldDefinition,
94 VariableDefinition,
95}
96
97impl DirectiveLocation {
98 pub fn as_str(self) -> &'static str {
99 match self {
100 DirectiveLocation::Query => "QUERY",
101 DirectiveLocation::Mutation => "MUTATION",
102 DirectiveLocation::Subscription => "SUBSCRIPTION",
103 DirectiveLocation::Field => "FIELD",
104 DirectiveLocation::FragmentDefinition => "FRAGMENT_DEFINITION",
105 DirectiveLocation::FragmentSpread => "FRAGMENT_SPREAD",
106 DirectiveLocation::InlineFragment => "INLINE_FRAGMENT",
107 DirectiveLocation::Schema => "SCHEMA",
108 DirectiveLocation::Scalar => "SCALAR",
109 DirectiveLocation::Object => "OBJECT",
110 DirectiveLocation::FieldDefinition => "FIELD_DEFINITION",
111 DirectiveLocation::ArgumentDefinition => "ARGUMENT_DEFINITION",
112 DirectiveLocation::Interface => "INTERFACE",
113 DirectiveLocation::Union => "UNION",
114 DirectiveLocation::Enum => "ENUM",
115 DirectiveLocation::EnumValue => "ENUM_VALUE",
116 DirectiveLocation::InputObject => "INPUT_OBJECT",
117 DirectiveLocation::InputFieldDefinition => "INPUT_FIELD_DEFINITION",
118 DirectiveLocation::VariableDefinition => "VARIABLE_DEFINITION",
119 }
120 }
121
122 pub(crate) fn all_locations() -> &'static [&'static str] {
123 &[
124 "QUERY",
125 "MUTATION",
126 "SUBSCRIPTION",
127 "FIELD",
128 "FRAGMENT_DEFINITION",
129 "FRAGMENT_SPREAD",
130 "INLINE_FRAGMENT",
131 "SCHEMA",
132 "SCALAR",
133 "OBJECT",
134 "FIELD_DEFINITION",
135 "ARGUMENT_DEFINITION",
136 "INTERFACE",
137 "UNION",
138 "ENUM",
139 "ENUM_VALUE",
140 "INPUT_OBJECT",
141 "INPUT_FIELD_DEFINITION",
142 "VARIABLE_DEFINITION",
143 ]
144 }
145}
146
147#[derive(Debug)]
148pub struct MalformedDirectiveLocation(pub String);
149
150impl FromStr for DirectiveLocation {
151 type Err = MalformedDirectiveLocation;
152
153 fn from_str(s: &str) -> Result<Self, Self::Err> {
154 Ok(match s {
155 "QUERY" => DirectiveLocation::Query,
156 "MUTATION" => DirectiveLocation::Mutation,
157 "SUBSCRIPTION" => DirectiveLocation::Subscription,
158 "FIELD" => DirectiveLocation::Field,
159 "FRAGMENT_DEFINITION" => DirectiveLocation::FragmentDefinition,
160 "FRAGMENT_SPREAD" => DirectiveLocation::FragmentSpread,
161 "INLINE_FRAGMENT" => DirectiveLocation::InlineFragment,
162 "SCHEMA" => DirectiveLocation::Schema,
163 "SCALAR" => DirectiveLocation::Scalar,
164 "OBJECT" => DirectiveLocation::Object,
165 "FIELD_DEFINITION" => DirectiveLocation::FieldDefinition,
166 "ARGUMENT_DEFINITION" => DirectiveLocation::ArgumentDefinition,
167 "INTERFACE" => DirectiveLocation::Interface,
168 "UNION" => DirectiveLocation::Union,
169 "ENUM" => DirectiveLocation::Enum,
170 "ENUM_VALUE" => DirectiveLocation::EnumValue,
171 "INPUT_OBJECT" => DirectiveLocation::InputObject,
172 "INPUT_FIELD_DEFINITION" => DirectiveLocation::InputFieldDefinition,
173 "VARIABLE_DEFINITION" => DirectiveLocation::VariableDefinition,
174 _ => return Err(MalformedDirectiveLocation(s.to_string())),
175 })
176 }
177}
178
179impl std::fmt::Display for DirectiveLocation {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 write!(f, "{}", self.as_str())
182 }
183}
184
185pub trait TypeSystemId: Copy {
186 type Reader<'a>;
187
188 fn read(self, ast: &TypeSystemDocument) -> Self::Reader<'_>;
189}
190
191#[derive(Clone, Copy)]
192struct ReadContext<'a, I> {
193 id: I,
194 document: &'a TypeSystemDocument,
195}
196
197impl super::TypeSystemDocument {
198 pub fn read<T>(&self, id: T) -> T::Reader<'_>
199 where
200 T: TypeSystemId,
201 {
202 id.read(self)
203 }
204}
205
206impl TypeSystemDocument {
207 pub fn definitions(&self) -> Iter<'_, Definition<'_>> {
208 Iter::new(
209 IdRange::new(
210 DefinitionId::new(0),
211 DefinitionId::new(self.definitions.len()),
212 ),
213 self,
214 )
215 }
216
217 pub fn directive_definitions(&self) -> impl Iterator<Item = DirectiveDefinition<'_>> + '_ {
218 self.directive_definitions
219 .iter()
220 .enumerate()
221 .map(|(index, _)| self.read(DirectiveDefinitionId::new(index)))
222 }
223}
224
225pub mod storage {
226 pub use super::{
227 definitions::DefinitionRecord,
228 generated::{
229 arguments::ArgumentRecord,
230 descriptions::DescriptionRecord,
231 directives::{DirectiveDefinitionRecord, DirectiveRecord},
232 enums::EnumDefinitionRecord,
233 enums::EnumValueDefinitionRecord,
234 fields::FieldDefinitionRecord,
235 input_objects::InputObjectDefinitionRecord,
236 input_values::InputValueDefinitionRecord,
237 interfaces::InterfaceDefinitionRecord,
238 objects::ObjectDefinitionRecord,
239 scalars::ScalarDefinitionRecord,
240 schemas::{RootOperationTypeDefinitionRecord, SchemaDefinitionRecord},
241 unions::{UnionDefinitionRecord, UnionMemberRecord},
242 },
243 types::TypeRecord,
244 };
245}