apollo_smith/
document.rs

1use crate::directive::DirectiveDef;
2use crate::enum_::EnumTypeDef;
3use crate::fragment::FragmentDef;
4use crate::input_object::InputObjectTypeDef;
5use crate::interface::InterfaceTypeDef;
6use crate::object::ObjectTypeDef;
7use crate::operation::OperationDef;
8use crate::scalar::ScalarTypeDef;
9use crate::schema::SchemaDef;
10use crate::union::UnionTypeDef;
11use apollo_compiler::ast;
12
13/// The `__Document` type represents a GraphQL document.A GraphQL Document describes a complete file or request string operated on by a GraphQL service or client.
14/// A document contains multiple definitions, either executable or representative of a GraphQL type system.
15///
16/// *Document*:
17///     OperationDefinition*
18///     FragmentDefinition*
19///     SchemaDefinition*
20///     ScalarTypeDefinition*
21///     ObjectTypeDefinition*
22///     InterfaceTypeDefinition*
23///     UnionTypeDefinition*
24///     EnumTypeDefinition*
25///     InputObjectDefinition*
26///     DirectiveDefinition*
27///
28/// Detailed documentation can be found in [GraphQL spec](https://spec.graphql.org/October2021/#sec-Document).
29#[derive(Debug, Clone)]
30pub struct Document {
31    pub(crate) operation_definitions: Vec<OperationDef>,
32    pub(crate) fragment_definitions: Vec<FragmentDef>,
33    pub(crate) schema_definition: Option<SchemaDef>,
34    // Type definitions
35    pub(crate) scalar_type_definitions: Vec<ScalarTypeDef>,
36    pub(crate) object_type_definitions: Vec<ObjectTypeDef>,
37    pub(crate) interface_type_definitions: Vec<InterfaceTypeDef>,
38    pub(crate) union_type_definitions: Vec<UnionTypeDef>,
39    pub(crate) enum_type_definitions: Vec<EnumTypeDef>,
40    pub(crate) input_object_type_definitions: Vec<InputObjectTypeDef>,
41    pub(crate) directive_definitions: Vec<DirectiveDef>,
42}
43
44impl From<Document> for ast::Document {
45    fn from(doc: Document) -> Self {
46        fn extend(
47            new_doc: &mut ast::Document,
48            items: impl IntoIterator<Item = impl Into<ast::Definition>>,
49        ) {
50            new_doc
51                .definitions
52                .extend(items.into_iter().map(|x| x.into()));
53        }
54
55        let Document {
56            operation_definitions,
57            fragment_definitions,
58            schema_definition,
59            scalar_type_definitions,
60            object_type_definitions,
61            interface_type_definitions,
62            union_type_definitions,
63            enum_type_definitions,
64            input_object_type_definitions,
65            directive_definitions,
66        } = doc;
67        let mut new_doc = Self::new();
68        extend(&mut new_doc, operation_definitions);
69        extend(&mut new_doc, fragment_definitions);
70        extend(&mut new_doc, schema_definition);
71        extend(&mut new_doc, scalar_type_definitions);
72        extend(&mut new_doc, object_type_definitions);
73        extend(&mut new_doc, interface_type_definitions);
74        extend(&mut new_doc, union_type_definitions);
75        extend(&mut new_doc, enum_type_definitions);
76        extend(&mut new_doc, input_object_type_definitions);
77        extend(&mut new_doc, directive_definitions);
78        new_doc
79    }
80}
81
82impl TryFrom<apollo_parser::cst::Document> for Document {
83    type Error = crate::FromError;
84
85    fn try_from(doc: apollo_parser::cst::Document) -> Result<Self, Self::Error> {
86        let mut enum_defs = Vec::new();
87        let mut object_defs = Vec::new();
88        let mut schema_def = None;
89        let mut directive_defs = Vec::new();
90        let mut scalar_defs = Vec::new();
91        let mut operation_defs = Vec::new();
92        let mut interface_defs = Vec::new();
93        let mut union_defs = Vec::new();
94        let mut input_object_defs = Vec::new();
95        let mut fragment_defs = Vec::new();
96
97        for definition in doc.definitions() {
98            match definition {
99                apollo_parser::cst::Definition::EnumTypeDefinition(enum_def) => {
100                    enum_defs.push(EnumTypeDef::try_from(enum_def)?);
101                }
102                apollo_parser::cst::Definition::EnumTypeExtension(enum_def) => {
103                    enum_defs.push(EnumTypeDef::try_from(enum_def)?);
104                }
105                apollo_parser::cst::Definition::ObjectTypeDefinition(obj_def) => {
106                    object_defs.push(ObjectTypeDef::try_from(obj_def)?);
107                }
108                apollo_parser::cst::Definition::ObjectTypeExtension(obj_def) => {
109                    object_defs.push(ObjectTypeDef::try_from(obj_def)?);
110                }
111                apollo_parser::cst::Definition::SchemaDefinition(schema_definition) => {
112                    schema_def = Some(SchemaDef::try_from(schema_definition)?);
113                }
114                apollo_parser::cst::Definition::SchemaExtension(schema_definition) => {
115                    schema_def = Some(SchemaDef::try_from(schema_definition)?);
116                }
117                apollo_parser::cst::Definition::DirectiveDefinition(dir_def) => {
118                    directive_defs.push(DirectiveDef::try_from(dir_def)?);
119                }
120                apollo_parser::cst::Definition::ScalarTypeDefinition(scalar_def) => {
121                    scalar_defs.push(ScalarTypeDef::try_from(scalar_def)?)
122                }
123                apollo_parser::cst::Definition::ScalarTypeExtension(scalar_def) => {
124                    scalar_defs.push(ScalarTypeDef::try_from(scalar_def)?)
125                }
126                apollo_parser::cst::Definition::OperationDefinition(operation_def) => {
127                    operation_defs.push(OperationDef::try_from(operation_def)?)
128                }
129                apollo_parser::cst::Definition::InterfaceTypeDefinition(interface_def) => {
130                    interface_defs.push(InterfaceTypeDef::try_from(interface_def)?)
131                }
132                apollo_parser::cst::Definition::InterfaceTypeExtension(interface_def) => {
133                    interface_defs.push(InterfaceTypeDef::try_from(interface_def)?)
134                }
135                apollo_parser::cst::Definition::UnionTypeDefinition(union_def) => {
136                    union_defs.push(UnionTypeDef::try_from(union_def)?)
137                }
138                apollo_parser::cst::Definition::UnionTypeExtension(union_def) => {
139                    union_defs.push(UnionTypeDef::try_from(union_def)?)
140                }
141                apollo_parser::cst::Definition::InputObjectTypeDefinition(input_object_def) => {
142                    input_object_defs.push(InputObjectTypeDef::try_from(input_object_def)?)
143                }
144                apollo_parser::cst::Definition::InputObjectTypeExtension(input_object_def) => {
145                    input_object_defs.push(InputObjectTypeDef::try_from(input_object_def)?)
146                }
147                apollo_parser::cst::Definition::FragmentDefinition(fragment_def) => {
148                    fragment_defs.push(FragmentDef::try_from(fragment_def)?)
149                }
150            }
151        }
152
153        Ok(Self {
154            operation_definitions: operation_defs,
155            fragment_definitions: fragment_defs,
156            schema_definition: schema_def,
157            scalar_type_definitions: scalar_defs,
158            object_type_definitions: object_defs,
159            interface_type_definitions: interface_defs,
160            union_type_definitions: union_defs,
161            enum_type_definitions: enum_defs,
162            input_object_type_definitions: input_object_defs,
163            directive_definitions: directive_defs,
164        })
165    }
166}
167
168impl From<Document> for String {
169    fn from(doc: Document) -> Self {
170        ast::Document::from(doc).to_string()
171    }
172}