libgraphql_parser/ast/directive_annotation.rs
1use crate::ast::Argument;
2use crate::ast::ast_node::append_span_source_slice;
3use crate::ast::AstNode;
4use crate::ast::DelimiterPair;
5use crate::ast::Name;
6use crate::ByteSpan;
7use crate::SourceMap;
8use crate::SourceSpan;
9use crate::token::GraphQLToken;
10use inherent::inherent;
11
12/// A directive annotation applied to a definition or field
13/// (e.g. `@deprecated(reason: "Use newField")`).
14///
15/// See
16/// [Directives](https://spec.graphql.org/September2025/#sec-Language.Directives)
17/// in the spec. Note: this represents an *applied* directive
18/// (an annotation), not a directive *definition*.
19#[derive(Clone, Debug, PartialEq)]
20pub struct DirectiveAnnotation<'src> {
21 pub arguments: Vec<Argument<'src>>,
22 pub name: Name<'src>,
23 pub span: ByteSpan,
24 pub syntax: Option<Box<DirectiveAnnotationSyntax<'src>>>,
25}
26
27/// Syntax detail for a [`DirectiveAnnotation`].
28#[derive(Clone, Debug, PartialEq)]
29pub struct DirectiveAnnotationSyntax<'src> {
30 pub argument_parens: Option<DelimiterPair<'src>>,
31 pub at_sign: GraphQLToken<'src>,
32}
33
34impl<'src> DirectiveAnnotation<'src> {
35 /// Returns the name of this directive annotation as a string
36 /// slice.
37 ///
38 /// Convenience accessor for `self.name.value`.
39 #[inline]
40 pub fn name_value(&self) -> &str {
41 self.name.value.as_ref()
42 }
43}
44
45#[inherent]
46impl AstNode for DirectiveAnnotation<'_> {
47 /// See [`AstNode::append_source()`](crate::ast::AstNode::append_source).
48 pub fn append_source(
49 &self,
50 sink: &mut String,
51 source: Option<&str>,
52 ) {
53 if let Some(src) = source {
54 append_span_source_slice(
55 self.span, sink, src,
56 );
57 }
58 }
59
60 /// Returns this directive annotation's byte-offset span within the
61 /// source text.
62 ///
63 /// The returned [`ByteSpan`] can be resolved to line/column
64 /// positions via [`source_span()`](Self::source_span) or
65 /// [`ByteSpan::resolve()`].
66 #[inline]
67 pub fn byte_span(&self) -> ByteSpan {
68 self.span
69 }
70
71 /// Resolves this directive annotation's position to line/column
72 /// coordinates using the given [`SourceMap`].
73 ///
74 /// Returns [`None`] if the byte offsets cannot be resolved
75 /// (e.g. the span was synthetically constructed without
76 /// valid position data).
77 #[inline]
78 pub fn source_span(
79 &self,
80 source_map: &SourceMap,
81 ) -> Option<SourceSpan> {
82 self.byte_span().resolve(source_map)
83 }
84}