Skip to main content

libgraphql_parser/ast/
field_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::InputValueDefinition;
6use crate::ast::Name;
7use crate::ast::StringValue;
8use crate::ast::TypeAnnotation;
9use crate::ByteSpan;
10use crate::SourceMap;
11use crate::SourceSpan;
12use crate::token::GraphQLToken;
13use inherent::inherent;
14
15/// A field definition within an object type or interface
16/// type.
17///
18/// See
19/// [Field Definitions](https://spec.graphql.org/September2025/#FieldsDefinition)
20/// in the spec.
21#[derive(Clone, Debug, PartialEq)]
22pub struct FieldDefinition<'src> {
23    pub parameters: Vec<InputValueDefinition<'src>>,
24    pub description: Option<StringValue<'src>>,
25    pub directives: Vec<DirectiveAnnotation<'src>>,
26    pub field_type: TypeAnnotation<'src>,
27    pub name: Name<'src>,
28    pub span: ByteSpan,
29    pub syntax: Option<Box<FieldDefinitionSyntax<'src>>>,
30}
31
32/// Syntax detail for a [`FieldDefinition`].
33#[derive(Clone, Debug, PartialEq)]
34pub struct FieldDefinitionSyntax<'src> {
35    pub argument_parens: Option<DelimiterPair<'src>>,
36    pub colon: GraphQLToken<'src>,
37}
38
39impl<'src> FieldDefinition<'src> {
40    /// Returns the name of this field definition as a string
41    /// slice.
42    ///
43    /// Convenience accessor for `self.name.value`.
44    #[inline]
45    pub fn name_value(&self) -> &str {
46        self.name.value.as_ref()
47    }
48}
49
50#[inherent]
51impl AstNode for FieldDefinition<'_> {
52    /// See [`AstNode::append_source()`](crate::ast::AstNode::append_source).
53    pub fn append_source(
54        &self,
55        sink: &mut String,
56        source: Option<&str>,
57    ) {
58        if let Some(src) = source {
59            append_span_source_slice(
60                self.span, sink, src,
61            );
62        }
63    }
64
65    /// Returns this field definition's byte-offset span within the
66    /// source text.
67    ///
68    /// The returned [`ByteSpan`] can be resolved to line/column
69    /// positions via [`source_span()`](Self::source_span) or
70    /// [`ByteSpan::resolve()`].
71    #[inline]
72    pub fn byte_span(&self) -> ByteSpan {
73        self.span
74    }
75
76    /// Resolves this field definition's position to line/column
77    /// coordinates using the given [`SourceMap`].
78    ///
79    /// Returns [`None`] if the byte offsets cannot be resolved
80    /// (e.g. the span was synthetically constructed without
81    /// valid position data).
82    #[inline]
83    pub fn source_span(
84        &self,
85        source_map: &SourceMap,
86    ) -> Option<SourceSpan> {
87        self.byte_span().resolve(source_map)
88    }
89}