Skip to main content

libgraphql_parser/ast/
value.rs

1use crate::ast::AstNode;
2use crate::ast::BooleanValue;
3use crate::ast::EnumValue;
4use crate::ast::FloatValue;
5use crate::ast::IntValue;
6use crate::ast::ListValue;
7use crate::ast::NullValue;
8use crate::ast::ObjectValue;
9use crate::ast::StringValue;
10use crate::ast::VariableReference;
11use crate::ByteSpan;
12use crate::SourceMap;
13use crate::SourceSpan;
14use inherent::inherent;
15
16/// A GraphQL input value.
17///
18/// Represents all possible GraphQL value literals as defined
19/// in the
20/// [Input Values](https://spec.graphql.org/September2025/#sec-Input-Values)
21/// section of the spec.
22#[derive(Clone, Debug, PartialEq)]
23pub enum Value<'src> {
24    Boolean(BooleanValue<'src>),
25    Enum(EnumValue<'src>),
26    Float(FloatValue<'src>),
27    Int(IntValue<'src>),
28    List(ListValue<'src>),
29    Null(NullValue<'src>),
30    Object(ObjectValue<'src>),
31    String(StringValue<'src>),
32    Variable(VariableReference<'src>),
33}
34
35#[inherent]
36impl AstNode for Value<'_> {
37    /// See [`AstNode::append_source()`](crate::ast::AstNode::append_source).
38    pub fn append_source(
39        &self,
40        sink: &mut String,
41        source: Option<&str>,
42    ) {
43        match self {
44            Value::Boolean(v) => {
45                v.append_source(sink, source)
46            },
47            Value::Enum(v) => {
48                v.append_source(sink, source)
49            },
50            Value::Float(v) => {
51                v.append_source(sink, source)
52            },
53            Value::Int(v) => {
54                v.append_source(sink, source)
55            },
56            Value::List(v) => {
57                v.append_source(sink, source)
58            },
59            Value::Null(v) => {
60                v.append_source(sink, source)
61            },
62            Value::Object(v) => {
63                v.append_source(sink, source)
64            },
65            Value::String(v) => {
66                v.append_source(sink, source)
67            },
68            Value::Variable(v) => {
69                v.append_source(sink, source)
70            },
71        }
72    }
73
74    /// Returns this value's byte-offset span within the source
75    /// text.
76    ///
77    /// The returned [`ByteSpan`] can be resolved to line/column
78    /// positions via [`source_span()`](Self::source_span) or
79    /// [`ByteSpan::resolve()`].
80    pub fn byte_span(&self) -> ByteSpan {
81        match self {
82            Self::Boolean(v) => v.span,
83            Self::Enum(v) => v.span,
84            Self::Float(v) => v.span,
85            Self::Int(v) => v.span,
86            Self::List(v) => v.span,
87            Self::Null(v) => v.span,
88            Self::Object(v) => v.span,
89            Self::String(v) => v.span,
90            Self::Variable(v) => v.span,
91        }
92    }
93
94    /// Resolves this value's position to line/column
95    /// coordinates using the given [`SourceMap`].
96    ///
97    /// Returns [`None`] if the byte offsets cannot be resolved
98    /// (e.g. the span was synthetically constructed without
99    /// valid position data).
100    pub fn source_span(
101        &self,
102        source_map: &SourceMap,
103    ) -> Option<SourceSpan> {
104        self.byte_span().resolve(source_map)
105    }
106}