Skip to main content

libgraphql_parser/ast/
schema_definition.rs

1use crate::ast::ast_node::append_span_source_slice;
2use crate::ast::AstNode;
3use crate::ast::DelimiterPair;
4use crate::ast::DirectiveAnnotation;
5use crate::ast::RootOperationTypeDefinition;
6use crate::ast::StringValue;
7use crate::ByteSpan;
8use crate::SourceMap;
9use crate::SourceSpan;
10use crate::token::GraphQLToken;
11use inherent::inherent;
12
13/// A GraphQL schema definition.
14///
15/// See
16/// [Schema](https://spec.graphql.org/September2025/#sec-Schema)
17/// in the spec.
18///
19/// # Spec invariant
20///
21/// The spec grammar uses `RootOperationTypeDefinition+`
22/// (the `+` list quantifier), requiring at least one
23/// root operation type definition. For a spec-valid
24/// node, `root_operations` is always non-empty.
25#[derive(Clone, Debug, PartialEq)]
26pub struct SchemaDefinition<'src> {
27    pub description: Option<StringValue<'src>>,
28    pub directives: Vec<DirectiveAnnotation<'src>>,
29    pub root_operations:
30        Vec<RootOperationTypeDefinition<'src>>,
31    pub span: ByteSpan,
32    pub syntax: Option<Box<SchemaDefinitionSyntax<'src>>>,
33}
34
35/// Syntax detail for a [`SchemaDefinition`].
36#[derive(Clone, Debug, PartialEq)]
37pub struct SchemaDefinitionSyntax<'src> {
38    pub braces: DelimiterPair<'src>,
39    pub schema_keyword: GraphQLToken<'src>,
40}
41
42#[inherent]
43impl AstNode for SchemaDefinition<'_> {
44    /// See [`AstNode::append_source()`](crate::ast::AstNode::append_source).
45    pub fn append_source(
46        &self,
47        sink: &mut String,
48        source: Option<&str>,
49    ) {
50        if let Some(src) = source {
51            append_span_source_slice(
52                self.span, sink, src,
53            );
54        }
55    }
56
57    /// Returns this schema definition's byte-offset span within the
58    /// source text.
59    ///
60    /// The returned [`ByteSpan`] can be resolved to line/column
61    /// positions via [`source_span()`](Self::source_span) or
62    /// [`ByteSpan::resolve()`].
63    #[inline]
64    pub fn byte_span(&self) -> ByteSpan {
65        self.span
66    }
67
68    /// Resolves this schema definition's position to line/column
69    /// coordinates using the given [`SourceMap`].
70    ///
71    /// Returns [`None`] if the byte offsets cannot be resolved
72    /// (e.g. the span was synthetically constructed without
73    /// valid position data).
74    #[inline]
75    pub fn source_span(
76        &self,
77        source_map: &SourceMap,
78    ) -> Option<SourceSpan> {
79        self.byte_span().resolve(source_map)
80    }
81}