apollo_compiler/ast/
impls.rs

1use super::*;
2use crate::name;
3use crate::parser::Parser;
4use crate::parser::SourceSpan;
5use crate::schema::SchemaBuilder;
6use crate::validation::DiagnosticList;
7use crate::validation::Valid;
8use crate::validation::WithErrors;
9use crate::ExecutableDocument;
10use crate::Schema;
11use std::fmt;
12use std::hash;
13use std::path::Path;
14use std::sync::OnceLock;
15
16impl Document {
17    /// Create an empty document
18    pub fn new() -> Self {
19        Self {
20            sources: Default::default(),
21            definitions: Vec::new(),
22        }
23    }
24
25    /// Return a new configurable parser
26    pub fn parser() -> Parser {
27        Parser::default()
28    }
29
30    /// Parse `input` with the default configuration
31    ///
32    /// `path` is the filesystem path (or arbitrary string) used in diagnostics
33    /// to identify this source file to users.
34    pub fn parse(
35        source_text: impl Into<String>,
36        path: impl AsRef<Path>,
37    ) -> Result<Self, WithErrors<Self>> {
38        Self::parser().parse_ast(source_text, path)
39    }
40
41    /// Validate as an executable document, as much as possible without a schema
42    pub fn validate_standalone_executable(&self) -> Result<(), DiagnosticList> {
43        let mut errors = DiagnosticList::new(self.sources.clone());
44        let type_system_definitions_are_errors = true;
45        let executable = crate::executable::from_ast::document_from_ast(
46            None,
47            self,
48            &mut errors,
49            type_system_definitions_are_errors,
50        );
51        crate::executable::validation::validate_standalone_executable(&mut errors, &executable);
52        errors.into_result()
53    }
54
55    /// Build a schema with this AST document as its sole input.
56    #[allow(clippy::result_large_err)] // Typically not called very often
57    pub fn to_schema(&self) -> Result<Schema, WithErrors<Schema>> {
58        let mut builder = Schema::builder();
59        let executable_definitions_are_errors = true;
60        builder.add_ast_document(self, executable_definitions_are_errors);
61        builder.build()
62    }
63
64    /// Build and validate a schema with this AST document as its sole input.
65    #[allow(clippy::result_large_err)] // Typically not called very often
66    pub fn to_schema_validate(&self) -> Result<Valid<Schema>, WithErrors<Schema>> {
67        let mut builder = Schema::builder();
68        let executable_definitions_are_errors = true;
69        builder.add_ast_document(self, executable_definitions_are_errors);
70        let (mut schema, mut errors) = builder.build_inner();
71        crate::schema::validation::validate_schema(&mut errors, &mut schema);
72        errors.into_valid_result(schema)
73    }
74
75    /// Build an executable document from this AST, with the given schema
76    #[allow(clippy::result_large_err)] // Typically not called very often
77    pub fn to_executable(
78        &self,
79        schema: &Valid<Schema>,
80    ) -> Result<ExecutableDocument, WithErrors<ExecutableDocument>> {
81        let mut errors = DiagnosticList::new(self.sources.clone());
82        let document = self.to_executable_inner(schema, &mut errors);
83        errors.into_result_with(document)
84    }
85
86    /// Build and validate an executable document from this AST, with the given schema
87    #[allow(clippy::result_large_err)] // Typically not called very often
88    pub fn to_executable_validate(
89        &self,
90        schema: &Valid<Schema>,
91    ) -> Result<Valid<ExecutableDocument>, WithErrors<ExecutableDocument>> {
92        let mut errors = DiagnosticList::new(self.sources.clone());
93        let document = self.to_executable_inner(schema, &mut errors);
94        crate::executable::validation::validate_executable_document(&mut errors, schema, &document);
95        errors.into_valid_result(document)
96    }
97
98    pub(crate) fn to_executable_inner(
99        &self,
100        schema: &Valid<Schema>,
101        errors: &mut DiagnosticList,
102    ) -> ExecutableDocument {
103        let type_system_definitions_are_errors = true;
104        crate::executable::from_ast::document_from_ast(
105            Some(schema),
106            self,
107            errors,
108            type_system_definitions_are_errors,
109        )
110    }
111
112    /// Build a schema and executable document from this AST containing a mixture
113    /// of type system definitions and executable definitions, and validate them.
114    /// This is mostly useful for unit tests.
115    pub fn to_mixed_validate(
116        &self,
117    ) -> Result<(Valid<Schema>, Valid<ExecutableDocument>), DiagnosticList> {
118        let mut builder = SchemaBuilder::new();
119        let executable_definitions_are_errors = false;
120        let type_system_definitions_are_errors = false;
121        builder.add_ast_document(self, executable_definitions_are_errors);
122        let (mut schema, mut errors) = builder.build_inner();
123        let executable = crate::executable::from_ast::document_from_ast(
124            Some(&schema),
125            self,
126            &mut errors,
127            type_system_definitions_are_errors,
128        );
129        crate::schema::validation::validate_schema(&mut errors, &mut schema);
130        crate::executable::validation::validate_executable_document(
131            &mut errors,
132            &schema,
133            &executable,
134        );
135        errors
136            .into_result()
137            .map(|()| (Valid(schema), Valid(executable)))
138    }
139
140    serialize_method!();
141}
142
143/// `source` is ignored for comparison
144impl PartialEq for Document {
145    fn eq(&self, other: &Self) -> bool {
146        self.definitions == other.definitions
147    }
148}
149
150impl Eq for Document {}
151
152impl hash::Hash for Document {
153    fn hash<H: hash::Hasher>(&self, state: &mut H) {
154        self.definitions.hash(state);
155    }
156}
157
158impl Default for Document {
159    fn default() -> Self {
160        Self::new()
161    }
162}
163
164impl fmt::Debug for Document {
165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166        // Skip two not-useful indentation levels
167        for def in &self.definitions {
168            def.fmt(f)?;
169            f.write_str("\n")?;
170        }
171        Ok(())
172    }
173}
174
175impl Definition {
176    /// Returns true if this is an executable definition (operation or fragment).
177    pub fn is_executable_definition(&self) -> bool {
178        matches!(
179            self,
180            Self::OperationDefinition(_) | Self::FragmentDefinition(_)
181        )
182    }
183
184    /// Returns true if this is an extension of another definition.
185    pub fn is_extension_definition(&self) -> bool {
186        matches!(
187            self,
188            Self::SchemaExtension(_)
189                | Self::ScalarTypeExtension(_)
190                | Self::ObjectTypeExtension(_)
191                | Self::InterfaceTypeExtension(_)
192                | Self::UnionTypeExtension(_)
193                | Self::EnumTypeExtension(_)
194                | Self::InputObjectTypeExtension(_)
195        )
196    }
197
198    pub(crate) fn describe(&self) -> &'static str {
199        match self {
200            Self::OperationDefinition(_) => "an operation definition",
201            Self::FragmentDefinition(_) => "a fragment definition",
202            Self::DirectiveDefinition(_) => "a directive definition",
203            Self::ScalarTypeDefinition(_) => "a scalar type definition",
204            Self::ObjectTypeDefinition(_) => "an object type definition",
205            Self::InterfaceTypeDefinition(_) => "an interface type definition",
206            Self::UnionTypeDefinition(_) => "a union type definition",
207            Self::EnumTypeDefinition(_) => "an enum type definition",
208            Self::InputObjectTypeDefinition(_) => "an input object type definition",
209            Self::SchemaDefinition(_) => "a schema definition",
210            Self::SchemaExtension(_) => "a schema extension",
211            Self::ScalarTypeExtension(_) => "a scalar type extension",
212            Self::ObjectTypeExtension(_) => "an object type extension",
213            Self::InterfaceTypeExtension(_) => "an interface type extension",
214            Self::UnionTypeExtension(_) => "a union type extension",
215            Self::EnumTypeExtension(_) => "an enum type extension",
216            Self::InputObjectTypeExtension(_) => "an input object type extension",
217        }
218    }
219
220    /// If this node was parsed from a source file, returns the file ID and source span
221    /// (start and end byte offsets) within that file.
222    pub fn location(&self) -> Option<SourceSpan> {
223        match self {
224            Self::OperationDefinition(def) => def.location(),
225            Self::FragmentDefinition(def) => def.location(),
226            Self::DirectiveDefinition(def) => def.location(),
227            Self::SchemaDefinition(def) => def.location(),
228            Self::ScalarTypeDefinition(def) => def.location(),
229            Self::ObjectTypeDefinition(def) => def.location(),
230            Self::InterfaceTypeDefinition(def) => def.location(),
231            Self::UnionTypeDefinition(def) => def.location(),
232            Self::EnumTypeDefinition(def) => def.location(),
233            Self::InputObjectTypeDefinition(def) => def.location(),
234            Self::SchemaExtension(def) => def.location(),
235            Self::ScalarTypeExtension(def) => def.location(),
236            Self::ObjectTypeExtension(def) => def.location(),
237            Self::InterfaceTypeExtension(def) => def.location(),
238            Self::UnionTypeExtension(def) => def.location(),
239            Self::EnumTypeExtension(def) => def.location(),
240            Self::InputObjectTypeExtension(def) => def.location(),
241        }
242    }
243
244    /// Return the name of this type definition or extension.
245    ///
246    /// Operations may be anonymous, and schema definitions and extensions never have a name.
247    /// In those cases this method returns `None`.
248    pub fn name(&self) -> Option<&Name> {
249        match self {
250            Self::OperationDefinition(def) => def.name.as_ref(),
251            Self::FragmentDefinition(def) => Some(&def.name),
252            Self::DirectiveDefinition(def) => Some(&def.name),
253            Self::SchemaDefinition(_) => None,
254            Self::ScalarTypeDefinition(def) => Some(&def.name),
255            Self::ObjectTypeDefinition(def) => Some(&def.name),
256            Self::InterfaceTypeDefinition(def) => Some(&def.name),
257            Self::UnionTypeDefinition(def) => Some(&def.name),
258            Self::EnumTypeDefinition(def) => Some(&def.name),
259            Self::InputObjectTypeDefinition(def) => Some(&def.name),
260            Self::SchemaExtension(_) => None,
261            Self::ScalarTypeExtension(def) => Some(&def.name),
262            Self::ObjectTypeExtension(def) => Some(&def.name),
263            Self::InterfaceTypeExtension(def) => Some(&def.name),
264            Self::UnionTypeExtension(def) => Some(&def.name),
265            Self::EnumTypeExtension(def) => Some(&def.name),
266            Self::InputObjectTypeExtension(def) => Some(&def.name),
267        }
268    }
269
270    pub fn directives(&self) -> &DirectiveList {
271        static EMPTY: DirectiveList = DirectiveList(Vec::new());
272        match self {
273            Self::DirectiveDefinition(_) => &EMPTY,
274            Self::OperationDefinition(def) => &def.directives,
275            Self::FragmentDefinition(def) => &def.directives,
276            Self::SchemaDefinition(def) => &def.directives,
277            Self::ScalarTypeDefinition(def) => &def.directives,
278            Self::ObjectTypeDefinition(def) => &def.directives,
279            Self::InterfaceTypeDefinition(def) => &def.directives,
280            Self::UnionTypeDefinition(def) => &def.directives,
281            Self::EnumTypeDefinition(def) => &def.directives,
282            Self::InputObjectTypeDefinition(def) => &def.directives,
283            Self::SchemaExtension(def) => &def.directives,
284            Self::ScalarTypeExtension(def) => &def.directives,
285            Self::ObjectTypeExtension(def) => &def.directives,
286            Self::InterfaceTypeExtension(def) => &def.directives,
287            Self::UnionTypeExtension(def) => &def.directives,
288            Self::EnumTypeExtension(def) => &def.directives,
289            Self::InputObjectTypeExtension(def) => &def.directives,
290        }
291    }
292
293    pub fn as_operation_definition(&self) -> Option<&Node<OperationDefinition>> {
294        if let Self::OperationDefinition(def) = self {
295            Some(def)
296        } else {
297            None
298        }
299    }
300
301    pub fn as_fragment_definition(&self) -> Option<&Node<FragmentDefinition>> {
302        if let Self::FragmentDefinition(def) = self {
303            Some(def)
304        } else {
305            None
306        }
307    }
308
309    pub fn as_directive_definition(&self) -> Option<&Node<DirectiveDefinition>> {
310        if let Self::DirectiveDefinition(def) = self {
311            Some(def)
312        } else {
313            None
314        }
315    }
316
317    pub fn as_schema_definition(&self) -> Option<&Node<SchemaDefinition>> {
318        if let Self::SchemaDefinition(def) = self {
319            Some(def)
320        } else {
321            None
322        }
323    }
324
325    pub fn as_scalar_type_definition(&self) -> Option<&Node<ScalarTypeDefinition>> {
326        if let Self::ScalarTypeDefinition(def) = self {
327            Some(def)
328        } else {
329            None
330        }
331    }
332
333    pub fn as_object_type_definition(&self) -> Option<&Node<ObjectTypeDefinition>> {
334        if let Self::ObjectTypeDefinition(def) = self {
335            Some(def)
336        } else {
337            None
338        }
339    }
340
341    pub fn as_interface_type_definition(&self) -> Option<&Node<InterfaceTypeDefinition>> {
342        if let Self::InterfaceTypeDefinition(def) = self {
343            Some(def)
344        } else {
345            None
346        }
347    }
348
349    pub fn as_union_type_definition(&self) -> Option<&Node<UnionTypeDefinition>> {
350        if let Self::UnionTypeDefinition(def) = self {
351            Some(def)
352        } else {
353            None
354        }
355    }
356
357    pub fn as_enum_type_definition(&self) -> Option<&Node<EnumTypeDefinition>> {
358        if let Self::EnumTypeDefinition(def) = self {
359            Some(def)
360        } else {
361            None
362        }
363    }
364
365    pub fn as_input_object_type_definition(&self) -> Option<&Node<InputObjectTypeDefinition>> {
366        if let Self::InputObjectTypeDefinition(def) = self {
367            Some(def)
368        } else {
369            None
370        }
371    }
372
373    pub fn as_schema_extension(&self) -> Option<&Node<SchemaExtension>> {
374        if let Self::SchemaExtension(def) = self {
375            Some(def)
376        } else {
377            None
378        }
379    }
380
381    pub fn as_scalar_type_extension(&self) -> Option<&Node<ScalarTypeExtension>> {
382        if let Self::ScalarTypeExtension(def) = self {
383            Some(def)
384        } else {
385            None
386        }
387    }
388
389    pub fn as_object_type_extension(&self) -> Option<&Node<ObjectTypeExtension>> {
390        if let Self::ObjectTypeExtension(def) = self {
391            Some(def)
392        } else {
393            None
394        }
395    }
396
397    pub fn as_interface_type_extension(&self) -> Option<&Node<InterfaceTypeExtension>> {
398        if let Self::InterfaceTypeExtension(def) = self {
399            Some(def)
400        } else {
401            None
402        }
403    }
404
405    pub fn as_union_type_extension(&self) -> Option<&Node<UnionTypeExtension>> {
406        if let Self::UnionTypeExtension(def) = self {
407            Some(def)
408        } else {
409            None
410        }
411    }
412
413    pub fn as_enum_type_extension(&self) -> Option<&Node<EnumTypeExtension>> {
414        if let Self::EnumTypeExtension(def) = self {
415            Some(def)
416        } else {
417            None
418        }
419    }
420
421    pub fn as_input_object_type_extension(&self) -> Option<&Node<InputObjectTypeExtension>> {
422        if let Self::InputObjectTypeExtension(def) = self {
423            Some(def)
424        } else {
425            None
426        }
427    }
428
429    serialize_method!();
430}
431
432impl fmt::Debug for Definition {
433    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434        // Skip the enum variant name as it’s redundant with the struct name in it
435        match self {
436            Self::OperationDefinition(def) => def.fmt(f),
437            Self::FragmentDefinition(def) => def.fmt(f),
438            Self::DirectiveDefinition(def) => def.fmt(f),
439            Self::SchemaDefinition(def) => def.fmt(f),
440            Self::ScalarTypeDefinition(def) => def.fmt(f),
441            Self::ObjectTypeDefinition(def) => def.fmt(f),
442            Self::InterfaceTypeDefinition(def) => def.fmt(f),
443            Self::UnionTypeDefinition(def) => def.fmt(f),
444            Self::EnumTypeDefinition(def) => def.fmt(f),
445            Self::InputObjectTypeDefinition(def) => def.fmt(f),
446            Self::SchemaExtension(def) => def.fmt(f),
447            Self::ScalarTypeExtension(def) => def.fmt(f),
448            Self::ObjectTypeExtension(def) => def.fmt(f),
449            Self::InterfaceTypeExtension(def) => def.fmt(f),
450            Self::UnionTypeExtension(def) => def.fmt(f),
451            Self::EnumTypeExtension(def) => def.fmt(f),
452            Self::InputObjectTypeExtension(def) => def.fmt(f),
453        }
454    }
455}
456
457impl OperationDefinition {
458    serialize_method!();
459}
460
461impl FragmentDefinition {
462    serialize_method!();
463}
464
465impl DirectiveDefinition {
466    /// Returns the definition of an argument by a given name.
467    pub fn argument_by_name(&self, name: &str) -> Option<&Node<InputValueDefinition>> {
468        self.arguments.iter().find(|argument| argument.name == name)
469    }
470
471    /// Returns the definition of an argument by a given name.
472    pub fn argument_by_name_mut(&mut self, name: &str) -> Option<&mut Node<InputValueDefinition>> {
473        self.arguments
474            .iter_mut()
475            .find(|argument| argument.name == name)
476    }
477
478    serialize_method!();
479}
480
481impl SchemaDefinition {
482    serialize_method!();
483}
484
485impl ScalarTypeDefinition {
486    serialize_method!();
487}
488
489impl ObjectTypeDefinition {
490    serialize_method!();
491}
492
493impl InterfaceTypeDefinition {
494    serialize_method!();
495}
496
497impl UnionTypeDefinition {
498    serialize_method!();
499}
500
501impl EnumTypeDefinition {
502    serialize_method!();
503}
504
505impl InputObjectTypeDefinition {
506    serialize_method!();
507}
508
509impl SchemaExtension {
510    serialize_method!();
511}
512
513impl ScalarTypeExtension {
514    serialize_method!();
515}
516
517impl ObjectTypeExtension {
518    serialize_method!();
519}
520
521impl InterfaceTypeExtension {
522    serialize_method!();
523}
524
525impl UnionTypeExtension {
526    serialize_method!();
527}
528
529impl EnumTypeExtension {
530    serialize_method!();
531}
532
533impl InputObjectTypeExtension {
534    serialize_method!();
535}
536
537impl DirectiveList {
538    pub fn new() -> Self {
539        Self(Vec::new())
540    }
541
542    /// Returns an iterator of directives with the given name.
543    ///
544    /// This method is best for repeatable directives.
545    /// See also [`get`][Self::get] for non-repeatable directives.
546    pub fn get_all<'def: 'name, 'name>(
547        &'def self,
548        name: &'name str,
549    ) -> impl Iterator<Item = &'def Node<Directive>> + 'name {
550        self.0.iter().filter(move |dir| dir.name == name)
551    }
552
553    /// Returns an iterator of mutable directives with the given name.
554    ///
555    /// This method is best for repeatable directives.
556    /// See also [`get`][Self::get] for non-repeatable directives.
557    pub fn get_all_mut<'def: 'name, 'name>(
558        &'def mut self,
559        name: &'name str,
560    ) -> impl Iterator<Item = &'def mut Node<Directive>> + 'name {
561        self.0.iter_mut().filter(move |dir| dir.name == name)
562    }
563
564    /// Returns the first directive with the given name, if any.
565    ///
566    /// This method is best for non-repeatable directives.
567    /// See also [`get_all`][Self::get_all] for repeatable directives.
568    pub fn get(&self, name: &str) -> Option<&Node<Directive>> {
569        self.get_all(name).next()
570    }
571
572    /// Returns whether there is a directive with the given name
573    pub fn has(&self, name: &str) -> bool {
574        self.get(name).is_some()
575    }
576
577    /// Accepts either [`Node<Directive>`] or [`Directive`].
578    pub fn push(&mut self, directive: impl Into<Node<Directive>>) {
579        self.0.push(directive.into());
580    }
581
582    serialize_method!();
583}
584
585impl std::fmt::Debug for DirectiveList {
586    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
587        self.0.fmt(f)
588    }
589}
590
591impl std::ops::Deref for DirectiveList {
592    type Target = Vec<Node<Directive>>;
593
594    fn deref(&self) -> &Self::Target {
595        &self.0
596    }
597}
598
599impl std::ops::DerefMut for DirectiveList {
600    fn deref_mut(&mut self) -> &mut Self::Target {
601        &mut self.0
602    }
603}
604
605impl IntoIterator for DirectiveList {
606    type Item = Node<Directive>;
607
608    type IntoIter = std::vec::IntoIter<Node<Directive>>;
609
610    fn into_iter(self) -> Self::IntoIter {
611        self.0.into_iter()
612    }
613}
614
615impl<'a> IntoIterator for &'a DirectiveList {
616    type Item = &'a Node<Directive>;
617
618    type IntoIter = std::slice::Iter<'a, Node<Directive>>;
619
620    fn into_iter(self) -> Self::IntoIter {
621        self.0.iter()
622    }
623}
624
625impl<'a> IntoIterator for &'a mut DirectiveList {
626    type Item = &'a mut Node<Directive>;
627
628    type IntoIter = std::slice::IterMut<'a, Node<Directive>>;
629
630    fn into_iter(self) -> Self::IntoIter {
631        self.0.iter_mut()
632    }
633}
634
635impl FromIterator<Node<Directive>> for DirectiveList {
636    fn from_iter<T: IntoIterator<Item = Node<Directive>>>(iter: T) -> Self {
637        Self(iter.into_iter().collect())
638    }
639}
640
641impl FromIterator<Directive> for DirectiveList {
642    fn from_iter<T: IntoIterator<Item = Directive>>(iter: T) -> Self {
643        Self(iter.into_iter().map(Node::new).collect())
644    }
645}
646
647impl Directive {
648    pub fn new(name: Name) -> Self {
649        Self {
650            name,
651            arguments: Vec::new(),
652        }
653    }
654
655    /// Returns the value of the argument named `name`, accounting for nullability
656    /// and for the default value in `schema`’s directive definition.
657    pub fn argument_by_name<'doc_or_schema>(
658        &'doc_or_schema self,
659        name: &str,
660        schema: &'doc_or_schema Schema,
661    ) -> Result<&'doc_or_schema Node<Value>, ArgumentByNameError> {
662        Argument::argument_by_name(&self.arguments, name, || {
663            schema
664                .directive_definitions
665                .get(&self.name)
666                .ok_or(ArgumentByNameError::UndefinedDirective)?
667                .argument_by_name(name)
668                .ok_or(ArgumentByNameError::NoSuchArgument)
669        })
670    }
671
672    /// Returns the value of the argument named `name`, as specified in the directive application.
673    ///
674    /// Returns `None` if the directive application does not specify this argument.
675    ///
676    /// If the directive definition makes this argument nullable or defines a default value,
677    /// consider using [`argument_by_name`][Self::argument_by_name] instead.
678    pub fn specified_argument_by_name(&self, name: &str) -> Option<&Node<Value>> {
679        Argument::specified_argument_by_name(&self.arguments, name)
680    }
681
682    /// Returns the value of the argument named `name`, as specified in the directive application.
683    /// If there are other [`Node`] pointers to the same argument, this method will clone the
684    /// argument using [`Node::make_mut`].
685    ///
686    /// Returns `None` if the directive application does not specify this argument.
687    ///
688    /// If the directive definition makes this argument nullable or defines a default value,
689    /// consider using [`argument_by_name`][Self::argument_by_name] instead.
690    pub fn specified_argument_by_name_mut(&mut self, name: &str) -> Option<&mut Node<Value>> {
691        Argument::specified_argument_by_name_mut(&mut self.arguments, name)
692    }
693
694    serialize_method!();
695}
696
697impl Argument {
698    pub(crate) fn argument_by_name<'doc_or_def>(
699        arguments: &'doc_or_def [Node<Self>],
700        name: &str,
701        def: impl FnOnce() -> Result<&'doc_or_def Node<InputValueDefinition>, ArgumentByNameError>,
702    ) -> Result<&'doc_or_def Node<Value>, ArgumentByNameError> {
703        if let Some(value) = Self::specified_argument_by_name(arguments, name) {
704            Ok(value)
705        } else {
706            let argument_def = def()?;
707            if let Some(value) = &argument_def.default_value {
708                Ok(value)
709            } else if argument_def.ty.is_non_null() {
710                Err(ArgumentByNameError::RequiredArgumentNotSpecified)
711            } else {
712                Ok(Value::static_null())
713            }
714        }
715    }
716
717    pub(crate) fn specified_argument_by_name<'doc>(
718        arguments: &'doc [Node<Self>],
719        name: &str,
720    ) -> Option<&'doc Node<Value>> {
721        arguments
722            .iter()
723            .find_map(|arg| (arg.name == name).then_some(&arg.value))
724    }
725
726    pub(crate) fn specified_argument_by_name_mut<'doc>(
727        arguments: &'doc mut [Node<Self>],
728        name: &str,
729    ) -> Option<&'doc mut Node<Value>> {
730        arguments
731            .iter_mut()
732            .find_map(|arg| (arg.name == name).then_some(&mut arg.make_mut().value))
733    }
734}
735
736impl OperationType {
737    /// Get the name of this operation type as it would appear in GraphQL source code.
738    pub fn name(self) -> &'static str {
739        match self {
740            OperationType::Query => "query",
741            OperationType::Mutation => "mutation",
742            OperationType::Subscription => "subscription",
743        }
744    }
745
746    /// Get the default name of the object type for this operation type
747    pub const fn default_type_name(self) -> NamedType {
748        match self {
749            OperationType::Query => name!("Query"),
750            OperationType::Mutation => name!("Mutation"),
751            OperationType::Subscription => name!("Subscription"),
752        }
753    }
754
755    pub fn is_query(&self) -> bool {
756        matches!(self, Self::Query)
757    }
758
759    pub fn is_mutation(&self) -> bool {
760        matches!(self, Self::Mutation)
761    }
762
763    pub fn is_subscription(&self) -> bool {
764        matches!(self, Self::Subscription)
765    }
766
767    serialize_method!();
768}
769
770impl DirectiveLocation {
771    /// Get the name of this directive location as it would appear in GraphQL source code.
772    pub fn name(self) -> &'static str {
773        match self {
774            DirectiveLocation::Query => "QUERY",
775            DirectiveLocation::Mutation => "MUTATION",
776            DirectiveLocation::Subscription => "SUBSCRIPTION",
777            DirectiveLocation::Field => "FIELD",
778            DirectiveLocation::FragmentDefinition => "FRAGMENT_DEFINITION",
779            DirectiveLocation::FragmentSpread => "FRAGMENT_SPREAD",
780            DirectiveLocation::InlineFragment => "INLINE_FRAGMENT",
781            DirectiveLocation::VariableDefinition => "VARIABLE_DEFINITION",
782            DirectiveLocation::Schema => "SCHEMA",
783            DirectiveLocation::Scalar => "SCALAR",
784            DirectiveLocation::Object => "OBJECT",
785            DirectiveLocation::FieldDefinition => "FIELD_DEFINITION",
786            DirectiveLocation::ArgumentDefinition => "ARGUMENT_DEFINITION",
787            DirectiveLocation::Interface => "INTERFACE",
788            DirectiveLocation::Union => "UNION",
789            DirectiveLocation::Enum => "ENUM",
790            DirectiveLocation::EnumValue => "ENUM_VALUE",
791            DirectiveLocation::InputObject => "INPUT_OBJECT",
792            DirectiveLocation::InputFieldDefinition => "INPUT_FIELD_DEFINITION",
793        }
794    }
795}
796
797impl fmt::Debug for DirectiveLocation {
798    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
799        self.name().fmt(f)
800    }
801}
802
803impl From<OperationType> for DirectiveLocation {
804    fn from(ty: OperationType) -> Self {
805        match ty {
806            OperationType::Query => DirectiveLocation::Query,
807            OperationType::Mutation => DirectiveLocation::Mutation,
808            OperationType::Subscription => DirectiveLocation::Subscription,
809        }
810    }
811}
812
813impl VariableDefinition {
814    serialize_method!();
815}
816
817/// Create a static [`Type`] with GraphQL-like syntax
818///
819/// ```
820/// use apollo_compiler::ty;
821///
822/// assert_eq!(ty!(Obj).to_string(), "Obj");
823/// assert_eq!(ty!(Obj!).to_string(), "Obj!");
824/// assert_eq!(ty!([Obj]).to_string(), "[Obj]");
825/// assert_eq!(ty!([Obj]!).to_string(), "[Obj]!");
826/// assert_eq!(ty!([[[Obj ] !]]!).to_string(), "[[[Obj]!]]!");
827/// ```
828#[macro_export]
829macro_rules! ty {
830    ($name: ident) => {
831        $crate::ast::Type::Named($crate::name!($name))
832    };
833    ($name: ident !) => {
834        $crate::ast::Type::NonNullNamed($crate::name!($name))
835    };
836    ([ $($tt: tt)+ ]) => {
837        $crate::ast::Type::List(::std::boxed::Box::new($crate::ty!( $($tt)+ )))
838    };
839    ([ $($tt: tt)+ ]!) => {
840        $crate::ast::Type::NonNullList(::std::boxed::Box::new($crate::ty!( $($tt)+ )))
841    };
842}
843
844impl Type {
845    /// Returns this type made non-null, if it isn’t already.
846    pub fn non_null(self) -> Self {
847        match self {
848            Type::Named(name) => Type::NonNullNamed(name),
849            Type::List(inner) => Type::NonNullList(inner),
850            Type::NonNullNamed(_) => self,
851            Type::NonNullList(_) => self,
852        }
853    }
854
855    /// Returns this type made nullable, if it isn’t already.
856    pub fn nullable(self) -> Self {
857        match self {
858            Type::Named(_) => self,
859            Type::List(_) => self,
860            Type::NonNullNamed(name) => Type::Named(name),
861            Type::NonNullList(inner) => Type::List(inner),
862        }
863    }
864
865    /// Returns a list type whose items are this type.
866    pub fn list(self) -> Self {
867        Type::List(Box::new(self))
868    }
869
870    /// If the type is a list type (nullable or not), returns the inner item type.
871    ///
872    /// Otherwise returns `self` unchanged.
873    ///
874    /// # Example
875    /// ```
876    /// use apollo_compiler::ty;
877    /// // Returns the inner type of the list.
878    /// assert_eq!(ty!([Foo!]).item_type(), &ty!(Foo!));
879    /// // Not a list: returns the input.
880    /// assert_eq!(ty!(Foo!).item_type(), &ty!(Foo!));
881    /// ```
882    pub fn item_type(&self) -> &Self {
883        match self {
884            Type::List(inner) | Type::NonNullList(inner) => inner,
885            ty => ty,
886        }
887    }
888
889    /// Returns the inner named type, after unwrapping any non-null or list markers.
890    pub fn inner_named_type(&self) -> &NamedType {
891        match self {
892            Type::Named(name) | Type::NonNullNamed(name) => name,
893            Type::List(inner) | Type::NonNullList(inner) => inner.inner_named_type(),
894        }
895    }
896
897    /// Returns whether this type is non-null
898    pub fn is_non_null(&self) -> bool {
899        matches!(self, Type::NonNullNamed(_) | Type::NonNullList(_))
900    }
901
902    /// Returns whether this type is a list type (nullable or not)
903    pub fn is_list(&self) -> bool {
904        matches!(self, Type::List(_) | Type::NonNullList(_))
905    }
906
907    /// Returns whether this type is a named type (nullable or not), as opposed to a list type.
908    pub fn is_named(&self) -> bool {
909        matches!(self, Type::Named(_) | Type::NonNullNamed(_))
910    }
911
912    /// Can a value of this type be used when the `target` type is expected?
913    ///
914    /// Implementation of spec function
915    /// [_AreTypesCompatible()_](https://spec.graphql.org/draft/#AreTypesCompatible()).
916    pub fn is_assignable_to(&self, target: &Self) -> bool {
917        match (target, self) {
918            // Can't assign a nullable type to a non-nullable type.
919            (Type::NonNullNamed(_) | Type::NonNullList(_), Type::Named(_) | Type::List(_)) => false,
920            // Can't assign a list type to a non-list type.
921            (Type::Named(_) | Type::NonNullNamed(_), Type::List(_) | Type::NonNullList(_)) => false,
922            // Can't assign a non-list type to a list type.
923            (Type::List(_) | Type::NonNullList(_), Type::Named(_) | Type::NonNullNamed(_)) => false,
924            // Non-null named types can be assigned if they are the same.
925            (Type::NonNullNamed(left), Type::NonNullNamed(right)) => left == right,
926            // Non-null list types can be assigned if their inner types are compatible.
927            (Type::NonNullList(left), Type::NonNullList(right)) => right.is_assignable_to(left),
928            // Both nullable and non-nullable named types can be assigned to a nullable type of the
929            // same name.
930            (Type::Named(left), Type::Named(right) | Type::NonNullNamed(right)) => left == right,
931            // Nullable and non-nullable lists can be assigned to a matching nullable list type.
932            (Type::List(left), Type::List(right) | Type::NonNullList(right)) => {
933                right.is_assignable_to(left)
934            }
935        }
936    }
937
938    /// Parse the given source text as a reference to a type.
939    ///
940    /// `path` is the filesystem path (or arbitrary string) used in diagnostics
941    /// to identify this source file to users.
942    ///
943    /// Create a [`Parser`] to use different parser configuration.
944    pub fn parse(
945        source_text: impl Into<String>,
946        path: impl AsRef<Path>,
947    ) -> Result<Self, DiagnosticList> {
948        Parser::new().parse_type(source_text, path)
949    }
950
951    serialize_method!();
952}
953
954impl FieldDefinition {
955    /// Returns the definition of an argument by a given name.
956    pub fn argument_by_name(&self, name: &str) -> Option<&Node<InputValueDefinition>> {
957        self.arguments.iter().find(|argument| argument.name == name)
958    }
959
960    serialize_method!();
961}
962
963impl InputValueDefinition {
964    /// Returns true if usage sites are required to provide a value for this input value.
965    ///
966    /// An input value is required when:
967    /// - its type is non-null, and
968    /// - it does not have a default value
969    pub fn is_required(&self) -> bool {
970        self.ty.is_non_null() && self.default_value.is_none()
971    }
972
973    serialize_method!();
974}
975
976impl EnumValueDefinition {
977    serialize_method!();
978}
979
980impl Selection {
981    /// If this node was parsed from a source file, returns the file ID and source span
982    /// (start and end byte offsets) within that file.
983    pub fn location(&self) -> Option<SourceSpan> {
984        match self {
985            Self::Field(field) => field.location(),
986            Self::FragmentSpread(fragment) => fragment.location(),
987            Self::InlineFragment(fragment) => fragment.location(),
988        }
989    }
990
991    pub fn as_field(&self) -> Option<&Node<Field>> {
992        if let Self::Field(x) = self {
993            Some(x)
994        } else {
995            None
996        }
997    }
998
999    pub fn as_fragment_spread(&self) -> Option<&Node<FragmentSpread>> {
1000        if let Self::FragmentSpread(x) = self {
1001            Some(x)
1002        } else {
1003            None
1004        }
1005    }
1006
1007    pub fn as_inline_fragment(&self) -> Option<&Node<InlineFragment>> {
1008        if let Self::InlineFragment(x) = self {
1009            Some(x)
1010        } else {
1011            None
1012        }
1013    }
1014
1015    serialize_method!();
1016}
1017
1018impl Field {
1019    /// Get the name that will be used for this field selection in [response `data`].
1020    ///
1021    /// For example, in this operation, the response name is `sourceField`:
1022    /// ```graphql
1023    /// query GetField { sourceField }
1024    /// ```
1025    ///
1026    /// But in this operation that uses an alias, the response name is `responseField`:
1027    /// ```graphql
1028    /// query GetField { responseField: sourceField }
1029    /// ```
1030    ///
1031    /// [response `data`]: https://spec.graphql.org/draft/#sec-Response-Format
1032    pub fn response_name(&self) -> &Name {
1033        self.alias.as_ref().unwrap_or(&self.name)
1034    }
1035
1036    serialize_method!();
1037}
1038
1039impl FragmentSpread {
1040    serialize_method!();
1041}
1042
1043impl InlineFragment {
1044    serialize_method!();
1045}
1046
1047impl Value {
1048    pub fn is_null(&self) -> bool {
1049        matches!(self, Value::Null)
1050    }
1051
1052    pub fn as_enum(&self) -> Option<&Name> {
1053        if let Value::Enum(name) = self {
1054            Some(name)
1055        } else {
1056            None
1057        }
1058    }
1059
1060    pub fn as_variable(&self) -> Option<&Name> {
1061        if let Value::Variable(name) = self {
1062            Some(name)
1063        } else {
1064            None
1065        }
1066    }
1067
1068    pub fn as_str(&self) -> Option<&str> {
1069        if let Value::String(value) = self {
1070            Some(value)
1071        } else {
1072            None
1073        }
1074    }
1075
1076    /// Convert a [`FloatValue`] **_or [`IntValue`]_** to floating point representation.
1077    ///
1078    /// Returns `None` if the value is of a different kind, or if the conversion overflows.
1079    pub fn to_f64(&self) -> Option<f64> {
1080        match self {
1081            Value::Float(value) => value.try_to_f64().ok(),
1082            Value::Int(value) => value.try_to_f64().ok(),
1083            _ => None,
1084        }
1085    }
1086
1087    pub fn to_i32(&self) -> Option<i32> {
1088        if let Value::Int(value) = self {
1089            value.try_to_i32().ok()
1090        } else {
1091            None
1092        }
1093    }
1094
1095    pub fn to_bool(&self) -> Option<bool> {
1096        if let Value::Boolean(value) = *self {
1097            Some(value)
1098        } else {
1099            None
1100        }
1101    }
1102
1103    pub fn as_list(&self) -> Option<&[Node<Value>]> {
1104        if let Value::List(value) = self {
1105            Some(value)
1106        } else {
1107            None
1108        }
1109    }
1110
1111    pub fn as_object(&self) -> Option<&[(Name, Node<Value>)]> {
1112        if let Value::Object(value) = self {
1113            Some(value)
1114        } else {
1115            None
1116        }
1117    }
1118
1119    pub(crate) fn describe(&self) -> &'static str {
1120        match self {
1121            Value::Null => "null",
1122            Value::Enum(_) => "an enum",
1123            Value::Variable(_) => "a variable",
1124            Value::String(_) => "a string",
1125            Value::Float(_) => "a float",
1126            Value::Int(_) => "an integer",
1127            Value::Boolean(_) => "a boolean",
1128            Value::List(_) => "a list",
1129            Value::Object(_) => "an input object",
1130        }
1131    }
1132
1133    pub(crate) fn static_null() -> &'static Node<Self> {
1134        static NULL: OnceLock<Node<Value>> = OnceLock::new();
1135        NULL.get_or_init(|| Value::Null.into())
1136    }
1137
1138    serialize_method!();
1139}
1140
1141impl IntValue {
1142    /// Constructs from a string matching the [`IntValue`
1143    /// grammar specification](https://spec.graphql.org/October2021/#IntValue)
1144    ///
1145    /// To convert an `i32`, use `from` or `into` instead.
1146    pub fn new_parsed(text: &str) -> Self {
1147        debug_assert!(IntValue::valid_syntax(text), "{text:?}");
1148        Self(text.into())
1149    }
1150
1151    fn valid_syntax(text: &str) -> bool {
1152        match text.strip_prefix('-').unwrap_or(text).as_bytes() {
1153            [b'0'..=b'9'] => true,
1154            [b'1'..=b'9', rest @ ..] => rest.iter().all(|b| b.is_ascii_digit()),
1155            _ => false,
1156        }
1157    }
1158
1159    /// Returns the string representation
1160    pub fn as_str(&self) -> &str {
1161        &self.0
1162    }
1163
1164    /// Converts to `i32`, returning an error on overflow
1165    ///
1166    /// Note: parsing is expected to succeed with a correctly-constructed `IntValue`,
1167    /// leaving overflow as the only error case.
1168    pub fn try_to_i32(&self) -> Result<i32, std::num::ParseIntError> {
1169        self.0.parse()
1170    }
1171
1172    /// Converts to a finite `f64`, returning an error on overflow to infinity
1173    ///
1174    /// An `IntValue` signals integer syntax was used, but is also valid in contexts
1175    /// where a `Float` is expected.
1176    ///
1177    /// Note: parsing is expected to succeed with a correctly-constructed `IntValue`,
1178    /// leaving overflow as the only error case.
1179    pub fn try_to_f64(&self) -> Result<f64, FloatOverflowError> {
1180        try_to_f64(&self.0)
1181    }
1182}
1183
1184impl FloatValue {
1185    /// Constructs from a string matching the [`FloatValue`
1186    /// grammar specification](https://spec.graphql.org/October2021/#IntValue)
1187    ///
1188    /// To convert an `f64`, use `from` or `into` instead.
1189    pub fn new_parsed(text: &str) -> Self {
1190        debug_assert!(FloatValue::valid_syntax(text), "{text:?}");
1191        Self(text.into())
1192    }
1193
1194    fn valid_syntax(text: &str) -> bool {
1195        if let Some((mantissa, exponent)) = text.split_once(['e', 'E']) {
1196            let exponent = exponent.strip_prefix(['+', '-']).unwrap_or(exponent);
1197            if !exponent.bytes().all(|b| b.is_ascii_digit()) {
1198                return false;
1199            }
1200            if let Some((int, fract)) = mantissa.split_once('.') {
1201                Self::valid_fractional_syntax(int, fract)
1202            } else {
1203                IntValue::valid_syntax(mantissa)
1204            }
1205        } else {
1206            text.split_once('.')
1207                .is_some_and(|(int, fract)| Self::valid_fractional_syntax(int, fract))
1208        }
1209    }
1210
1211    fn valid_fractional_syntax(integer: &str, fractional: &str) -> bool {
1212        IntValue::valid_syntax(integer)
1213            && !fractional.is_empty()
1214            && fractional.bytes().all(|b| b.is_ascii_digit())
1215    }
1216
1217    /// Returns the string representation
1218    pub fn as_str(&self) -> &str {
1219        &self.0
1220    }
1221
1222    /// Converts to a finite `f64`, returning an error on overflow to infinity
1223    ///
1224    /// Note: parsing is expected to succeed with a correctly-constructed `FloatValue`,
1225    /// leaving overflow as the only error case.
1226    pub fn try_to_f64(&self) -> Result<f64, FloatOverflowError> {
1227        try_to_f64(&self.0)
1228    }
1229}
1230
1231fn try_to_f64(text: &str) -> Result<f64, FloatOverflowError> {
1232    let parsed = text.parse::<f64>();
1233    debug_assert!(parsed.is_ok(), "{}", parsed.unwrap_err());
1234    let Ok(float) = parsed else {
1235        return Err(FloatOverflowError {});
1236    };
1237    debug_assert!(!float.is_nan());
1238    if float.is_finite() {
1239        Ok(float)
1240    } else {
1241        Err(FloatOverflowError {})
1242    }
1243}
1244
1245impl From<i32> for IntValue {
1246    fn from(value: i32) -> Self {
1247        let text = value.to_string();
1248        debug_assert!(IntValue::valid_syntax(&text), "{text:?}");
1249        Self(text)
1250    }
1251}
1252
1253impl From<f64> for FloatValue {
1254    fn from(value: f64) -> Self {
1255        let mut text = value.to_string();
1256        if !text.contains('.') {
1257            text.push_str(".0")
1258        }
1259        debug_assert!(FloatValue::valid_syntax(&text), "{text:?}");
1260        Self(text)
1261    }
1262}
1263
1264impl fmt::Display for IntValue {
1265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1266        self.0.fmt(f)
1267    }
1268}
1269
1270impl fmt::Display for FloatValue {
1271    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1272        self.0.fmt(f)
1273    }
1274}
1275
1276impl fmt::Debug for IntValue {
1277    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1278        fmt::Display::fmt(&self.0, f)
1279    }
1280}
1281
1282impl fmt::Debug for FloatValue {
1283    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1284        fmt::Display::fmt(&self.0, f)
1285    }
1286}
1287
1288impl<'de> serde::Deserialize<'de> for IntValue {
1289    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1290    where
1291        D: serde::Deserializer<'de>,
1292    {
1293        const EXPECTING: &str = "a string in GraphQL IntValue syntax";
1294        struct Visitor;
1295        impl serde::de::Visitor<'_> for Visitor {
1296            type Value = IntValue;
1297
1298            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1299                formatter.write_str(EXPECTING)
1300            }
1301
1302            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1303            where
1304                E: serde::de::Error,
1305            {
1306                if IntValue::valid_syntax(v) {
1307                    Ok(IntValue(v.to_owned()))
1308                } else {
1309                    Err(E::invalid_value(serde::de::Unexpected::Str(v), &EXPECTING))
1310                }
1311            }
1312
1313            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1314            where
1315                E: serde::de::Error,
1316            {
1317                if IntValue::valid_syntax(&v) {
1318                    Ok(IntValue(v))
1319                } else {
1320                    Err(E::invalid_value(serde::de::Unexpected::Str(&v), &EXPECTING))
1321                }
1322            }
1323        }
1324        deserializer.deserialize_string(Visitor)
1325    }
1326}
1327
1328impl<'de> serde::Deserialize<'de> for FloatValue {
1329    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1330    where
1331        D: serde::Deserializer<'de>,
1332    {
1333        const EXPECTING: &str = "a string in GraphQL FloatValue syntax";
1334        struct Visitor;
1335        impl serde::de::Visitor<'_> for Visitor {
1336            type Value = FloatValue;
1337
1338            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1339                formatter.write_str(EXPECTING)
1340            }
1341
1342            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1343            where
1344                E: serde::de::Error,
1345            {
1346                if FloatValue::valid_syntax(v) {
1347                    Ok(FloatValue(v.to_owned()))
1348                } else {
1349                    Err(E::invalid_value(serde::de::Unexpected::Str(v), &EXPECTING))
1350                }
1351            }
1352
1353            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1354            where
1355                E: serde::de::Error,
1356            {
1357                if FloatValue::valid_syntax(&v) {
1358                    Ok(FloatValue(v))
1359                } else {
1360                    Err(E::invalid_value(serde::de::Unexpected::Str(&v), &EXPECTING))
1361                }
1362            }
1363        }
1364        deserializer.deserialize_string(Visitor)
1365    }
1366}
1367
1368impl serde::Serialize for IntValue {
1369    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1370    where
1371        S: serde::Serializer,
1372    {
1373        self.0.serialize(serializer)
1374    }
1375}
1376
1377impl serde::Serialize for FloatValue {
1378    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1379    where
1380        S: serde::Serializer,
1381    {
1382        self.0.serialize(serializer)
1383    }
1384}
1385
1386impl fmt::Display for FloatOverflowError {
1387    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1388        f.write_str("value magnitude too large to be converted to `f64`")
1389    }
1390}
1391
1392impl fmt::Debug for FloatOverflowError {
1393    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1394        fmt::Display::fmt(self, f)
1395    }
1396}
1397
1398impl From<Node<OperationDefinition>> for Definition {
1399    fn from(def: Node<OperationDefinition>) -> Self {
1400        Self::OperationDefinition(def)
1401    }
1402}
1403
1404impl From<Node<FragmentDefinition>> for Definition {
1405    fn from(def: Node<FragmentDefinition>) -> Self {
1406        Self::FragmentDefinition(def)
1407    }
1408}
1409
1410impl From<Node<DirectiveDefinition>> for Definition {
1411    fn from(def: Node<DirectiveDefinition>) -> Self {
1412        Self::DirectiveDefinition(def)
1413    }
1414}
1415
1416impl From<Node<SchemaDefinition>> for Definition {
1417    fn from(def: Node<SchemaDefinition>) -> Self {
1418        Self::SchemaDefinition(def)
1419    }
1420}
1421
1422impl From<Node<ScalarTypeDefinition>> for Definition {
1423    fn from(def: Node<ScalarTypeDefinition>) -> Self {
1424        Self::ScalarTypeDefinition(def)
1425    }
1426}
1427
1428impl From<Node<ObjectTypeDefinition>> for Definition {
1429    fn from(def: Node<ObjectTypeDefinition>) -> Self {
1430        Self::ObjectTypeDefinition(def)
1431    }
1432}
1433
1434impl From<Node<InterfaceTypeDefinition>> for Definition {
1435    fn from(def: Node<InterfaceTypeDefinition>) -> Self {
1436        Self::InterfaceTypeDefinition(def)
1437    }
1438}
1439
1440impl From<Node<UnionTypeDefinition>> for Definition {
1441    fn from(def: Node<UnionTypeDefinition>) -> Self {
1442        Self::UnionTypeDefinition(def)
1443    }
1444}
1445
1446impl From<Node<EnumTypeDefinition>> for Definition {
1447    fn from(def: Node<EnumTypeDefinition>) -> Self {
1448        Self::EnumTypeDefinition(def)
1449    }
1450}
1451
1452impl From<Node<InputObjectTypeDefinition>> for Definition {
1453    fn from(def: Node<InputObjectTypeDefinition>) -> Self {
1454        Self::InputObjectTypeDefinition(def)
1455    }
1456}
1457
1458impl From<Node<SchemaExtension>> for Definition {
1459    fn from(def: Node<SchemaExtension>) -> Self {
1460        Self::SchemaExtension(def)
1461    }
1462}
1463
1464impl From<Node<ScalarTypeExtension>> for Definition {
1465    fn from(def: Node<ScalarTypeExtension>) -> Self {
1466        Self::ScalarTypeExtension(def)
1467    }
1468}
1469
1470impl From<Node<ObjectTypeExtension>> for Definition {
1471    fn from(def: Node<ObjectTypeExtension>) -> Self {
1472        Self::ObjectTypeExtension(def)
1473    }
1474}
1475
1476impl From<Node<InterfaceTypeExtension>> for Definition {
1477    fn from(def: Node<InterfaceTypeExtension>) -> Self {
1478        Self::InterfaceTypeExtension(def)
1479    }
1480}
1481
1482impl From<Node<UnionTypeExtension>> for Definition {
1483    fn from(def: Node<UnionTypeExtension>) -> Self {
1484        Self::UnionTypeExtension(def)
1485    }
1486}
1487
1488impl From<Node<EnumTypeExtension>> for Definition {
1489    fn from(def: Node<EnumTypeExtension>) -> Self {
1490        Self::EnumTypeExtension(def)
1491    }
1492}
1493
1494impl From<Node<InputObjectTypeExtension>> for Definition {
1495    fn from(def: Node<InputObjectTypeExtension>) -> Self {
1496        Self::InputObjectTypeExtension(def)
1497    }
1498}
1499
1500impl From<OperationDefinition> for Definition {
1501    fn from(def: OperationDefinition) -> Self {
1502        Self::OperationDefinition(Node::new(def))
1503    }
1504}
1505
1506impl From<FragmentDefinition> for Definition {
1507    fn from(def: FragmentDefinition) -> Self {
1508        Self::FragmentDefinition(Node::new(def))
1509    }
1510}
1511
1512impl From<DirectiveDefinition> for Definition {
1513    fn from(def: DirectiveDefinition) -> Self {
1514        Self::DirectiveDefinition(Node::new(def))
1515    }
1516}
1517
1518impl From<SchemaDefinition> for Definition {
1519    fn from(def: SchemaDefinition) -> Self {
1520        Self::SchemaDefinition(Node::new(def))
1521    }
1522}
1523
1524impl From<ScalarTypeDefinition> for Definition {
1525    fn from(def: ScalarTypeDefinition) -> Self {
1526        Self::ScalarTypeDefinition(Node::new(def))
1527    }
1528}
1529
1530impl From<ObjectTypeDefinition> for Definition {
1531    fn from(def: ObjectTypeDefinition) -> Self {
1532        Self::ObjectTypeDefinition(Node::new(def))
1533    }
1534}
1535
1536impl From<InterfaceTypeDefinition> for Definition {
1537    fn from(def: InterfaceTypeDefinition) -> Self {
1538        Self::InterfaceTypeDefinition(Node::new(def))
1539    }
1540}
1541
1542impl From<UnionTypeDefinition> for Definition {
1543    fn from(def: UnionTypeDefinition) -> Self {
1544        Self::UnionTypeDefinition(Node::new(def))
1545    }
1546}
1547
1548impl From<EnumTypeDefinition> for Definition {
1549    fn from(def: EnumTypeDefinition) -> Self {
1550        Self::EnumTypeDefinition(Node::new(def))
1551    }
1552}
1553
1554impl From<InputObjectTypeDefinition> for Definition {
1555    fn from(def: InputObjectTypeDefinition) -> Self {
1556        Self::InputObjectTypeDefinition(Node::new(def))
1557    }
1558}
1559
1560impl From<SchemaExtension> for Definition {
1561    fn from(def: SchemaExtension) -> Self {
1562        Self::SchemaExtension(Node::new(def))
1563    }
1564}
1565
1566impl From<ScalarTypeExtension> for Definition {
1567    fn from(def: ScalarTypeExtension) -> Self {
1568        Self::ScalarTypeExtension(Node::new(def))
1569    }
1570}
1571
1572impl From<ObjectTypeExtension> for Definition {
1573    fn from(def: ObjectTypeExtension) -> Self {
1574        Self::ObjectTypeExtension(Node::new(def))
1575    }
1576}
1577
1578impl From<InterfaceTypeExtension> for Definition {
1579    fn from(def: InterfaceTypeExtension) -> Self {
1580        Self::InterfaceTypeExtension(Node::new(def))
1581    }
1582}
1583
1584impl From<UnionTypeExtension> for Definition {
1585    fn from(def: UnionTypeExtension) -> Self {
1586        Self::UnionTypeExtension(Node::new(def))
1587    }
1588}
1589
1590impl From<EnumTypeExtension> for Definition {
1591    fn from(def: EnumTypeExtension) -> Self {
1592        Self::EnumTypeExtension(Node::new(def))
1593    }
1594}
1595
1596impl From<InputObjectTypeExtension> for Definition {
1597    fn from(def: InputObjectTypeExtension) -> Self {
1598        Self::InputObjectTypeExtension(Node::new(def))
1599    }
1600}
1601
1602/// The Rust unit value a.k.a empty tuple converts to [`Value::Null`].
1603impl From<()> for Value {
1604    fn from(_value: ()) -> Self {
1605        Value::Null
1606    }
1607}
1608
1609impl From<f64> for Value {
1610    fn from(value: f64) -> Self {
1611        Value::Float(value.into())
1612    }
1613}
1614
1615impl From<i32> for Value {
1616    fn from(value: i32) -> Self {
1617        Value::Int(value.into())
1618    }
1619}
1620
1621impl From<&'_ str> for Value {
1622    fn from(value: &'_ str) -> Self {
1623        Value::String(value.into())
1624    }
1625}
1626
1627impl From<&'_ String> for Value {
1628    fn from(value: &'_ String) -> Self {
1629        Value::String(value.into())
1630    }
1631}
1632
1633impl From<String> for Value {
1634    fn from(value: String) -> Self {
1635        Value::String(value)
1636    }
1637}
1638
1639impl From<bool> for Value {
1640    fn from(value: bool) -> Self {
1641        Value::Boolean(value)
1642    }
1643}
1644
1645/// The Rust unit value a.k.a empty tuple converts to [`Value::Null`].
1646impl From<()> for Node<Value> {
1647    fn from(value: ()) -> Self {
1648        Node::new(value.into())
1649    }
1650}
1651
1652impl From<f64> for Node<Value> {
1653    fn from(value: f64) -> Self {
1654        Node::new(value.into())
1655    }
1656}
1657
1658impl From<i32> for Node<Value> {
1659    fn from(value: i32) -> Self {
1660        Node::new(value.into())
1661    }
1662}
1663
1664impl From<&'_ str> for Node<Value> {
1665    fn from(value: &'_ str) -> Self {
1666        Node::new(value.into())
1667    }
1668}
1669
1670impl From<&'_ String> for Node<Value> {
1671    fn from(value: &'_ String) -> Self {
1672        Node::new(value.into())
1673    }
1674}
1675
1676impl From<String> for Node<Value> {
1677    fn from(value: String) -> Self {
1678        Node::new(value.into())
1679    }
1680}
1681
1682impl From<bool> for Node<Value> {
1683    fn from(value: bool) -> Self {
1684        Node::new(value.into())
1685    }
1686}
1687
1688impl<N: Into<Name>, V: Into<Node<Value>>> From<(N, V)> for Node<Argument> {
1689    fn from((name, value): (N, V)) -> Self {
1690        Node::new(Argument {
1691            name: name.into(),
1692            value: value.into(),
1693        })
1694    }
1695}