Skip to main content

libgraphql_parser/ast/
type_definition.rs

1use crate::ast::AstNode;
2use crate::ast::DirectiveAnnotation;
3use crate::ast::EnumTypeDefinition;
4use crate::ast::InputObjectTypeDefinition;
5use crate::ast::InterfaceTypeDefinition;
6use crate::ast::Name;
7use crate::ast::ObjectTypeDefinition;
8use crate::ast::ScalarTypeDefinition;
9use crate::ast::StringValue;
10use crate::ast::UnionTypeDefinition;
11use crate::ByteSpan;
12use crate::SourceMap;
13use crate::SourceSpan;
14use inherent::inherent;
15
16/// A type definition in a GraphQL schema.
17///
18/// See
19/// [Types](https://spec.graphql.org/September2025/#sec-Types)
20/// in the spec.
21#[derive(Clone, Debug, PartialEq)]
22pub enum TypeDefinition<'src> {
23    Enum(EnumTypeDefinition<'src>),
24    InputObject(InputObjectTypeDefinition<'src>),
25    Interface(InterfaceTypeDefinition<'src>),
26    Object(ObjectTypeDefinition<'src>),
27    Scalar(ScalarTypeDefinition<'src>),
28    Union(UnionTypeDefinition<'src>),
29}
30
31impl<'src> TypeDefinition<'src> {
32    /// Returns the description string for this type definition,
33    /// if one is present.
34    pub fn description(&self) -> Option<&StringValue<'src>> {
35        match self {
36            Self::Enum(def) => def.description.as_ref(),
37            Self::InputObject(def) => def.description.as_ref(),
38            Self::Interface(def) => def.description.as_ref(),
39            Self::Object(def) => def.description.as_ref(),
40            Self::Scalar(def) => def.description.as_ref(),
41            Self::Union(def) => def.description.as_ref(),
42        }
43    }
44
45    /// Returns the directive annotations applied to this type definition.
46    pub fn directive_annotations(
47        &self,
48    ) -> &[DirectiveAnnotation<'src>] {
49        match self {
50            Self::Enum(def) => &def.directives,
51            Self::InputObject(def) => &def.directives,
52            Self::Interface(def) => &def.directives,
53            Self::Object(def) => &def.directives,
54            Self::Scalar(def) => &def.directives,
55            Self::Union(def) => &def.directives,
56        }
57    }
58
59    /// Returns the [`Name`] of this type definition.
60    pub fn name(&self) -> &Name<'src> {
61        match self {
62            Self::Enum(def) => &def.name,
63            Self::InputObject(def) => &def.name,
64            Self::Interface(def) => &def.name,
65            Self::Object(def) => &def.name,
66            Self::Scalar(def) => &def.name,
67            Self::Union(def) => &def.name,
68        }
69    }
70
71    /// Returns the name of this type definition as a string
72    /// slice.
73    ///
74    /// Convenience accessor for `self.name().value`.
75    pub fn name_value(&self) -> &str {
76        self.name().value.as_ref()
77    }
78}
79
80#[inherent]
81impl AstNode for TypeDefinition<'_> {
82    /// See [`AstNode::append_source()`](crate::ast::AstNode::append_source).
83    pub fn append_source(
84        &self,
85        sink: &mut String,
86        source: Option<&str>,
87    ) {
88        match self {
89            TypeDefinition::Enum(d) => {
90                d.append_source(sink, source)
91            },
92            TypeDefinition::InputObject(d) => {
93                d.append_source(sink, source)
94            },
95            TypeDefinition::Interface(d) => {
96                d.append_source(sink, source)
97            },
98            TypeDefinition::Object(d) => {
99                d.append_source(sink, source)
100            },
101            TypeDefinition::Scalar(d) => {
102                d.append_source(sink, source)
103            },
104            TypeDefinition::Union(d) => {
105                d.append_source(sink, source)
106            },
107        }
108    }
109
110    /// Returns this type definition's byte-offset span within
111    /// the source text.
112    ///
113    /// The returned [`ByteSpan`] can be resolved to line/column
114    /// positions via [`source_span()`](Self::source_span) or
115    /// [`ByteSpan::resolve()`].
116    pub fn byte_span(&self) -> ByteSpan {
117        match self {
118            Self::Enum(def) => def.span,
119            Self::InputObject(def) => def.span,
120            Self::Interface(def) => def.span,
121            Self::Object(def) => def.span,
122            Self::Scalar(def) => def.span,
123            Self::Union(def) => def.span,
124        }
125    }
126
127    /// Resolves this type definition's position to line/column
128    /// coordinates using the given [`SourceMap`].
129    ///
130    /// Returns [`None`] if the byte offsets cannot be resolved
131    /// (e.g. the span was synthetically constructed without
132    /// valid position data).
133    pub fn source_span(
134        &self,
135        source_map: &SourceMap,
136    ) -> Option<SourceSpan> {
137        self.byte_span().resolve(source_map)
138    }
139}