Skip to main content

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