juniper/
ast.rs

1use std::{borrow::Cow, fmt, hash::Hash, mem, slice, vec};
2
3use arcstr::ArcStr;
4use compact_str::CompactString;
5use indexmap::IndexMap;
6
7#[cfg(doc)]
8use self::TypeModifier::{List, NonNull};
9use crate::{
10    executor::Variables,
11    parser::Spanning,
12    value::{DefaultScalarValue, Scalar, ScalarValue, ToScalarValue},
13};
14
15/// Possible modifiers in a [`Type`] literal.
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum TypeModifier {
18    /// Non-`null` type (e.g. `<type>!`).
19    NonNull,
20
21    /// List of types (e.g. `[<type>]`).
22    List(Option<usize>),
23}
24
25/// Owned slice of [`TypeModifier`]s.
26#[derive(Clone, Debug)]
27pub enum TypeModifiers {
28    /// [`TypeModifier`]s known statically.
29    Static(&'static [TypeModifier]),
30
31    /// [`TypeModifier`]s built dynamically.
32    Dynamic(Box<[TypeModifier]>),
33}
34
35impl Default for TypeModifiers {
36    fn default() -> Self {
37        Self::Static(&[])
38    }
39}
40
41impl AsRef<[TypeModifier]> for TypeModifiers {
42    fn as_ref(&self) -> &[TypeModifier] {
43        match self {
44            Self::Static(s) => s,
45            Self::Dynamic(bs) => bs,
46        }
47    }
48}
49
50impl Extend<TypeModifier> for TypeModifiers {
51    fn extend<T: IntoIterator<Item = TypeModifier>>(&mut self, iter: T) {
52        for modifier in iter {
53            self.wrap(modifier);
54        }
55    }
56}
57
58impl TypeModifiers {
59    /// Wraps these [`TypeModifiers`] into the provided [`TypeModifier`].
60    fn wrap(&mut self, modifier: TypeModifier) {
61        *self = match (mem::take(self), modifier) {
62            (Self::Static(&[]), TypeModifier::NonNull) => Self::Static(&[TypeModifier::NonNull]),
63            (Self::Static(&[]), TypeModifier::List(None)) => {
64                Self::Static(&[TypeModifier::List(None)])
65            }
66            (Self::Static(&[TypeModifier::NonNull]), TypeModifier::List(None)) => {
67                Self::Static(&[TypeModifier::NonNull, TypeModifier::List(None)])
68            }
69            (Self::Static(s), modifier) => {
70                let mut vec: Vec<_> = s.to_vec();
71                vec.push(modifier);
72                Self::Dynamic(vec.into_boxed_slice())
73            }
74            (Self::Dynamic(s), modifier) => {
75                let mut vec = s.into_vec();
76                vec.push(modifier);
77                Self::Dynamic(vec.into_boxed_slice())
78            }
79        };
80    }
81
82    /// Removes the last [`TypeModifier`] from these [`TypeModifiers`], if there is any.
83    fn pop(&mut self) {
84        *self = match mem::take(self) {
85            Self::Static(s) => Self::Static(&s[..s.len() - 1]),
86            Self::Dynamic(s) if s.len() == 1 => Self::Static(&[]),
87            Self::Dynamic(s) => {
88                let mut vec = s.into_vec();
89                vec.pop();
90                Self::Dynamic(vec.into_boxed_slice())
91            }
92        }
93    }
94}
95
96/// Type literal in a syntax tree.
97///
98/// Carries no semantic information and might refer to types that don't exist.
99#[derive(Clone, Copy, Debug)]
100pub struct Type<N = ArcStr, M = TypeModifiers> {
101    /// Name of this [`Type`].
102    name: N,
103
104    /// Modifiers of this [`Type`].
105    ///
106    /// The first one is the innermost one.
107    modifiers: M,
108}
109
110impl<N, M> Eq for Type<N, M> where Self: PartialEq {}
111
112impl<N1, N2, M1, M2> PartialEq<Type<N2, M2>> for Type<N1, M1>
113where
114    N1: AsRef<str>,
115    N2: AsRef<str>,
116    M1: AsRef<[TypeModifier]>,
117    M2: AsRef<[TypeModifier]>,
118{
119    fn eq(&self, other: &Type<N2, M2>) -> bool {
120        self.name.as_ref() == other.name.as_ref()
121            && self.modifiers.as_ref() == other.modifiers.as_ref()
122    }
123}
124
125impl<N, M> fmt::Display for Type<N, M>
126where
127    N: AsRef<str>,
128    M: AsRef<[TypeModifier]>,
129{
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        match self.modifier() {
132            Some(TypeModifier::NonNull) => write!(f, "{}!", self.borrow_inner()),
133            Some(TypeModifier::List(..)) => write!(f, "[{}]", self.borrow_inner()),
134            None => write!(f, "{}", self.name.as_ref()),
135        }
136    }
137}
138
139impl<'a, N, M> From<&'a Type<N, M>> for BorrowedType<'a>
140where
141    N: AsRef<str>,
142    M: AsRef<[TypeModifier]>,
143{
144    fn from(value: &'a Type<N, M>) -> Self {
145        Self {
146            name: value.name.as_ref(),
147            modifiers: value.modifiers.as_ref(),
148        }
149    }
150}
151
152impl<N: AsRef<str>, M: AsRef<[TypeModifier]>> Type<N, M> {
153    /// Borrows the inner [`Type`] of this modified [`Type`], removing its topmost [`TypeModifier`].
154    ///
155    /// # Panics
156    ///
157    /// If this [`Type`] has no [`TypeModifier`]s.
158    pub(crate) fn borrow_inner(&self) -> BorrowedType<'_> {
159        let modifiers = self.modifiers.as_ref();
160        match modifiers.len() {
161            0 => panic!("no inner `Type` available"),
162            n => Type {
163                name: self.name.as_ref(),
164                modifiers: &modifiers[..n - 1],
165            },
166        }
167    }
168
169    /// Returns the name of this [`Type`].
170    ///
171    /// [`List`]s will return [`None`].
172    #[must_use]
173    pub fn name(&self) -> Option<&str> {
174        (!self.is_list()).then(|| self.name.as_ref())
175    }
176
177    /// Returns the innermost name of this [`Type`] by unpacking [`List`]s.
178    ///
179    /// All [`Type`] literals contain exactly one name.
180    #[must_use]
181    pub fn innermost_name(&self) -> &str {
182        self.name.as_ref()
183    }
184
185    /// Returns the topmost [`TypeModifier`] of this [`Type`], if any.
186    #[must_use]
187    pub fn modifier(&self) -> Option<&TypeModifier> {
188        self.modifiers().last()
189    }
190
191    /// Returns [`TypeModifier`]s of this [`Type`], if any.
192    ///
193    /// The first one is the innermost one.
194    #[must_use]
195    pub fn modifiers(&self) -> &[TypeModifier] {
196        self.modifiers.as_ref()
197    }
198
199    /// Indicates whether this [`Type`] is [`NonNull`].
200    #[must_use]
201    pub fn is_non_null(&self) -> bool {
202        match self.modifiers.as_ref().last() {
203            Some(TypeModifier::NonNull) => true,
204            Some(TypeModifier::List(..)) | None => false,
205        }
206    }
207
208    /// Indicates whether this [`Type`] represents a [`List`] (either `null`able or [`NonNull`]).
209    #[must_use]
210    pub fn is_list(&self) -> bool {
211        match self.modifiers.as_ref().last() {
212            Some(TypeModifier::NonNull) => self.borrow_inner().is_non_null(),
213            Some(TypeModifier::List(..)) => true,
214            None => false,
215        }
216    }
217}
218
219impl<N, M: Default> Type<N, M> {
220    /// Creates a new `null`able [`Type`] literal from the provided `name`.
221    #[must_use]
222    pub fn nullable(name: impl Into<N>) -> Self {
223        Self {
224            name: name.into(),
225            modifiers: M::default(),
226        }
227    }
228}
229
230impl<N, M: Extend<TypeModifier>> Type<N, M> {
231    /// Wraps this [`Type`] into the provided [`TypeModifier`].
232    fn wrap(mut self, modifier: TypeModifier) -> Self {
233        self.modifiers.extend([modifier]);
234        self
235    }
236
237    /// Wraps this [`Type`] into a [`List`] with the provided `expected_size`, if any.
238    #[must_use]
239    pub fn wrap_list(self, expected_size: Option<usize>) -> Self {
240        self.wrap(TypeModifier::List(expected_size))
241    }
242
243    /// Wraps this [`Type`] as a [`NonNull`] one.
244    #[must_use]
245    pub fn wrap_non_null(self) -> Self {
246        self.wrap(TypeModifier::NonNull)
247    }
248}
249
250impl<N: AsRef<str>> Type<N> {
251    /// Strips this [`Type`] from [`NonNull`], returning it as a `null`able one.
252    pub(crate) fn into_nullable(mut self) -> Self {
253        if self.is_non_null() {
254            self.modifiers.pop();
255        }
256        self
257    }
258}
259
260/// Borrowed variant of a [`Type`] literal.
261pub(crate) type BorrowedType<'a> = Type<&'a str, &'a [TypeModifier]>;
262
263impl<'a> BorrowedType<'a> {
264    /// Creates a [`NonNull`] [`BorrowedType`] literal from the provided `name`.
265    pub(crate) fn non_null(name: &'a str) -> Self {
266        Self {
267            name,
268            modifiers: &[TypeModifier::NonNull],
269        }
270    }
271
272    /// Borrows the inner [`Type`] of this [`List`] [`Type`], if it represents one.
273    pub(crate) fn borrow_list_inner(&self) -> Option<Self> {
274        let mut out = None;
275        for (n, m) in self.modifiers.iter().enumerate().rev() {
276            match m {
277                TypeModifier::NonNull => {}
278                TypeModifier::List(..) => {
279                    out = Some(Self {
280                        name: self.name,
281                        modifiers: &self.modifiers[..n],
282                    });
283                    break;
284                }
285            }
286        }
287        out
288    }
289}
290
291/// A JSON-like value that can be passed into the query execution, either
292/// out-of-band, or in-band as default variable values. These are _not_ constant
293/// and might contain variables.
294///
295/// Lists and objects variants are _spanned_, i.e. they contain a reference to
296/// their position in the source file, if available.
297#[expect(missing_docs, reason = "self-explanatory")]
298#[derive(Clone, Debug, PartialEq)]
299pub enum InputValue<S = DefaultScalarValue> {
300    Null,
301    Scalar(S),
302    Enum(String),
303    Variable(String),
304    List(Vec<Spanning<InputValue<S>>>),
305    Object(Vec<(Spanning<String>, Spanning<InputValue<S>>)>),
306}
307
308#[derive(Clone, Debug, PartialEq)]
309pub struct VariableDefinition<'a, S> {
310    pub var_type: Spanning<Type<&'a str>>,
311    pub default_value: Option<Spanning<InputValue<S>>>,
312    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
313}
314
315#[derive(Clone, Debug, PartialEq)]
316pub struct Arguments<'a, S> {
317    pub items: Vec<(Spanning<&'a str>, Spanning<InputValue<S>>)>,
318}
319
320#[derive(Clone, Debug, PartialEq)]
321pub struct VariableDefinitions<'a, S> {
322    pub items: Vec<(Spanning<&'a str>, VariableDefinition<'a, S>)>,
323}
324
325#[derive(Clone, Debug, PartialEq)]
326pub struct Field<'a, S> {
327    pub alias: Option<Spanning<&'a str>>,
328    pub name: Spanning<&'a str>,
329    pub arguments: Option<Spanning<Arguments<'a, S>>>,
330    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
331    pub selection_set: Option<Vec<Selection<'a, S>>>,
332}
333
334#[derive(Clone, Debug, PartialEq)]
335pub struct FragmentSpread<'a, S> {
336    pub name: Spanning<&'a str>,
337    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
338}
339
340#[derive(Clone, Debug, PartialEq)]
341pub struct InlineFragment<'a, S> {
342    pub type_condition: Option<Spanning<&'a str>>,
343    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
344    pub selection_set: Vec<Selection<'a, S>>,
345}
346
347/// Entry in a GraphQL selection set
348///
349/// This enum represents one of the three variants of a selection that exists
350/// in GraphQL: a field, a fragment spread, or an inline fragment. Each of the
351/// variants references their location in the query source.
352///
353/// ```text
354/// {
355///   field(withArg: 123) { subField }
356///   ...fragmentSpread
357///   ...on User {
358///     inlineFragmentField
359///   }
360/// }
361/// ```
362#[expect(missing_docs, reason = "self-explanatory")]
363#[derive(Clone, Debug, PartialEq)]
364pub enum Selection<'a, S = DefaultScalarValue> {
365    Field(Spanning<Field<'a, S>>),
366    FragmentSpread(Spanning<FragmentSpread<'a, S>>),
367    InlineFragment(Spanning<InlineFragment<'a, S>>),
368}
369
370#[derive(Clone, Debug, PartialEq)]
371pub struct Directive<'a, S> {
372    pub name: Spanning<&'a str>,
373    pub arguments: Option<Spanning<Arguments<'a, S>>>,
374}
375
376#[expect(missing_docs, reason = "self-explanatory")]
377#[derive(Clone, Copy, Debug, Eq, PartialEq)]
378pub enum OperationType {
379    Query,
380    Mutation,
381    Subscription,
382}
383
384#[expect(missing_docs, reason = "self-explanatory")]
385#[derive(Clone, Debug, PartialEq)]
386pub struct Operation<'a, S> {
387    pub operation_type: OperationType,
388    pub name: Option<Spanning<&'a str>>,
389    pub variable_definitions: Option<Spanning<VariableDefinitions<'a, S>>>,
390    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
391    pub selection_set: Vec<Selection<'a, S>>,
392}
393
394#[derive(Clone, Debug, PartialEq)]
395pub struct Fragment<'a, S> {
396    pub name: Spanning<&'a str>,
397    pub type_condition: Spanning<&'a str>,
398    pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
399    pub selection_set: Vec<Selection<'a, S>>,
400}
401
402#[doc(hidden)]
403#[derive(Clone, Debug, PartialEq)]
404pub enum Definition<'a, S> {
405    Operation(Spanning<Operation<'a, S>>),
406    Fragment(Spanning<Fragment<'a, S>>),
407}
408
409#[doc(hidden)]
410pub type Document<'a, S> = [Definition<'a, S>];
411#[doc(hidden)]
412pub type OwnedDocument<'a, S> = Vec<Definition<'a, S>>;
413
414/// Parsing of an unstructured [`InputValue`] into a Rust data type.
415///
416/// The conversion _can_ fail, and must in that case return an [`Err`]. Thus, not restricted in the
417/// definition of this trait, the returned [`Err`] should be convertible with the [`IntoFieldError`]
418/// trait to fit well into the library machinery.
419///
420/// [`IntoFieldError`]: crate::IntoFieldError
421pub trait FromInputValue<S = DefaultScalarValue>: Sized {
422    /// Type of this conversion error.
423    ///
424    /// Thus, not restricted, it should be convertible with the [`IntoFieldError`] trait to fit well
425    /// into the library machinery.
426    ///
427    /// [`IntoFieldError`]: crate::IntoFieldError
428    type Error;
429
430    /// Performs the conversion.
431    fn from_input_value(v: &InputValue<S>) -> Result<Self, Self::Error>;
432
433    /// Performs the conversion from an absent value (e.g. to distinguish
434    /// between implicit and explicit `null`).
435    ///
436    /// The default implementation just calls [`from_input_value()`] as if an
437    /// explicit `null` was provided.
438    ///
439    /// [`from_input_value()`]: FromInputValue::from_input_value
440    fn from_implicit_null() -> Result<Self, Self::Error> {
441        Self::from_input_value(&InputValue::<S>::Null)
442    }
443}
444
445/// Losslessly clones a Rust data type into an [`InputValue`].
446pub trait ToInputValue<S = DefaultScalarValue> {
447    /// Performs the conversion.
448    fn to_input_value(&self) -> InputValue<S>;
449}
450
451impl<S> InputValue<S> {
452    /// Construct a `null` value.
453    pub fn null() -> Self {
454        Self::Null
455    }
456
457    /// Construct a scalar value.
458    pub fn scalar<T: Into<S>>(v: T) -> Self {
459        Self::Scalar(v.into())
460    }
461
462    /// Construct an enum value.
463    pub fn enum_value<T: AsRef<str>>(s: T) -> Self {
464        Self::Enum(s.as_ref().into())
465    }
466
467    /// Construct a variable value.
468    pub fn variable<T: AsRef<str>>(v: T) -> Self {
469        Self::Variable(v.as_ref().into())
470    }
471
472    /// Construct a [`Spanning::unlocated`] list.
473    ///
474    /// Convenience function to make each [`InputValue`] in the input vector
475    /// not contain any location information. Can be used from [`ToInputValue`]
476    /// implementations, where no source code position information is available.
477    pub fn list(l: Vec<Self>) -> Self {
478        Self::List(l.into_iter().map(Spanning::unlocated).collect())
479    }
480
481    /// Construct a located list.
482    pub fn parsed_list(l: Vec<Spanning<Self>>) -> Self {
483        Self::List(l)
484    }
485
486    /// Construct aa [`Spanning::unlocated`] object.
487    ///
488    /// Similarly to [`InputValue::list`] it makes each key and value in the
489    /// given hash map not contain any location information.
490    pub fn object<K>(o: IndexMap<K, Self>) -> Self
491    where
492        K: AsRef<str> + Eq + Hash,
493    {
494        Self::Object(
495            o.into_iter()
496                .map(|(k, v)| {
497                    (
498                        Spanning::unlocated(k.as_ref().into()),
499                        Spanning::unlocated(v),
500                    )
501                })
502                .collect(),
503        )
504    }
505
506    /// Construct a located object.
507    pub fn parsed_object(o: Vec<(Spanning<String>, Spanning<Self>)>) -> Self {
508        Self::Object(o)
509    }
510
511    /// Resolves all variables of this [`InputValue`] to their actual `values`.
512    ///
513    /// If a variable is not present in the `values`:
514    /// - Returns [`None`] in case this is an [`InputValue::Variable`].
515    /// - Skips field in case of an [`InputValue::Object`] field.
516    /// - Replaces with an [`InputValue::Null`] in case of an
517    ///   [`InputValue::List`] element.
518    ///
519    /// This is done, because for an [`InputValue::Variable`] (or an
520    /// [`InputValue::Object`] field) a default value can be used later, if it's
521    /// provided. While on contrary, a single [`InputValue::List`] element
522    /// cannot have a default value.
523    #[must_use]
524    pub fn into_const(self, values: &Variables<S>) -> Option<Self>
525    where
526        S: Clone,
527    {
528        match self {
529            Self::Variable(v) => values.get(&v).cloned(),
530            Self::List(l) => Some(Self::List(
531                l.into_iter()
532                    .map(|s| s.map(|v| v.into_const(values).unwrap_or_else(Self::null)))
533                    .collect(),
534            )),
535            Self::Object(o) => Some(Self::Object(
536                o.into_iter()
537                    .filter_map(|(sk, sv)| sv.and_then(|v| v.into_const(values)).map(|sv| (sk, sv)))
538                    .collect(),
539            )),
540            v => Some(v),
541        }
542    }
543
544    /// Shorthand form of invoking [`FromInputValue::from_input_value()`].
545    pub fn convert<T: FromInputValue<S>>(&self) -> Result<T, T::Error> {
546        T::from_input_value(self)
547    }
548
549    /// Does the value represent a `null`?
550    pub fn is_null(&self) -> bool {
551        matches!(self, Self::Null)
552    }
553
554    /// Does the value represent a variable?
555    pub fn is_variable(&self) -> bool {
556        matches!(self, Self::Variable(_))
557    }
558
559    /// View the underlying enum value, if present.
560    pub fn as_enum_value(&self) -> Option<&str> {
561        match self {
562            Self::Enum(e) => Some(e.as_str()),
563            _ => None,
564        }
565    }
566
567    /// View the underlying scalar value, if present.
568    pub fn as_scalar(&self) -> Option<&S> {
569        match self {
570            Self::Scalar(s) => Some(s),
571            _ => None,
572        }
573    }
574
575    /// Converts this [`InputValue`] to a [`Spanning::unlocated`] object value.
576    ///
577    /// This constructs a new [`IndexMap`] containing references to the keys
578    /// and values of `self`.
579    pub fn to_object_value(&self) -> Option<IndexMap<&str, &Self>> {
580        match self {
581            Self::Object(o) => Some(
582                o.iter()
583                    .map(|(sk, sv)| (sk.item.as_str(), &sv.item))
584                    .collect(),
585            ),
586            _ => None,
587        }
588    }
589
590    /// Converts this [`InputValue`] to a [`Spanning::unlocated`] list value.
591    ///
592    /// This constructs a new [`Vec`] containing references to the values of
593    /// `self`.
594    pub fn to_list_value(&self) -> Option<Vec<&Self>> {
595        match self {
596            Self::List(l) => Some(l.iter().map(|s| &s.item).collect()),
597            _ => None,
598        }
599    }
600
601    /// Recursively finds all variables
602    pub fn referenced_variables(&self) -> Vec<&str> {
603        match self {
604            Self::Variable(name) => vec![name.as_str()],
605            Self::List(l) => l
606                .iter()
607                .flat_map(|v| v.item.referenced_variables())
608                .collect(),
609            Self::Object(o) => o
610                .iter()
611                .flat_map(|(_, v)| v.item.referenced_variables())
612                .collect(),
613            _ => vec![],
614        }
615    }
616
617    /// Compares equality with another [`InputValue``] ignoring any source
618    /// position information.
619    pub fn unlocated_eq(&self, other: &Self) -> bool
620    where
621        S: PartialEq,
622    {
623        match (self, other) {
624            (Self::Null, Self::Null) => true,
625            (Self::Scalar(s1), Self::Scalar(s2)) => s1 == s2,
626            (Self::Enum(s1), Self::Enum(s2)) | (Self::Variable(s1), Self::Variable(s2)) => s1 == s2,
627            (Self::List(l1), Self::List(l2)) => l1
628                .iter()
629                .zip(l2.iter())
630                .all(|(v1, v2)| v1.item.unlocated_eq(&v2.item)),
631            (Self::Object(o1), Self::Object(o2)) => {
632                o1.len() == o2.len()
633                    && o1.iter().all(|(sk1, sv1)| {
634                        o2.iter().any(|(sk2, sv2)| {
635                            sk1.item == sk2.item && sv1.item.unlocated_eq(&sv2.item)
636                        })
637                    })
638            }
639            _ => false,
640        }
641    }
642}
643
644impl<S: ScalarValue> fmt::Display for InputValue<S> {
645    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646        match self {
647            Self::Null => write!(f, "null"),
648            Self::Scalar(s) => fmt::Display::fmt(<&Scalar<_>>::from(s), f),
649            Self::Enum(v) => write!(f, "{v}"),
650            Self::Variable(v) => write!(f, "${v}"),
651            Self::List(v) => {
652                write!(f, "[")?;
653                for (i, spanning) in v.iter().enumerate() {
654                    spanning.item.fmt(f)?;
655                    if i < v.len() - 1 {
656                        write!(f, ", ")?;
657                    }
658                }
659                write!(f, "]")
660            }
661            Self::Object(o) => {
662                write!(f, "{{")?;
663                for (i, (k, v)) in o.iter().enumerate() {
664                    write!(f, "{}: ", k.item)?;
665                    v.item.fmt(f)?;
666                    if i < o.len() - 1 {
667                        write!(f, ", ")?;
668                    }
669                }
670                write!(f, "}}")
671            }
672        }
673    }
674}
675
676/// Conversion into an [`InputValue`].
677///
678/// This trait exists to work around [orphan rules] and allow to specify custom efficient
679/// conversions whenever some custom [`ScalarValue`] is involved
680/// (`impl IntoInputValue<CustomScalarValue> for ForeignType` would work, while
681/// `impl From<ForeignType> for InputValue<CustomScalarValue>` wound not).
682///
683/// This trait is used inside [`graphql_input_value!`] macro expansion and implementing it allows to
684/// put values of the implementor type there.
685///
686/// [`graphql_input_value!`]: crate::graphql_input_value
687/// [orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
688pub trait IntoInputValue<S> {
689    /// Converts this value into an [`InputValue`].
690    #[must_use]
691    fn into_input_value(self) -> InputValue<S>;
692}
693
694impl<S> IntoInputValue<S> for InputValue<S> {
695    fn into_input_value(self) -> Self {
696        self
697    }
698}
699
700impl<T, S> IntoInputValue<S> for Option<T>
701where
702    T: IntoInputValue<S>,
703{
704    fn into_input_value(self) -> InputValue<S> {
705        match self {
706            Some(v) => v.into_input_value(),
707            None => InputValue::Null,
708        }
709    }
710}
711
712impl<T, S> IntoInputValue<S> for &T
713where
714    T: ToScalarValue<S> + ?Sized,
715{
716    fn into_input_value(self) -> InputValue<S> {
717        InputValue::Scalar(self.to_scalar_value())
718    }
719}
720
721impl<S> IntoInputValue<S> for String
722where
723    String: Into<S>,
724{
725    fn into_input_value(self) -> InputValue<S> {
726        InputValue::Scalar(self.into())
727    }
728}
729
730impl<S> IntoInputValue<S> for Cow<'_, str>
731where
732    for<'a> &'a str: IntoInputValue<S>,
733    String: IntoInputValue<S>,
734{
735    fn into_input_value(self) -> InputValue<S> {
736        match self {
737            Cow::Borrowed(s) => s.into_input_value(),
738            Cow::Owned(s) => s.into_input_value(),
739        }
740    }
741}
742
743impl<S: ScalarValue> IntoInputValue<S> for ArcStr
744where
745    ArcStr: ToScalarValue<S>,
746{
747    fn into_input_value(self) -> InputValue<S> {
748        InputValue::Scalar(self.to_scalar_value())
749    }
750}
751
752impl<S: ScalarValue> IntoInputValue<S> for CompactString
753where
754    CompactString: ToScalarValue<S>,
755{
756    fn into_input_value(self) -> InputValue<S> {
757        InputValue::Scalar(self.to_scalar_value())
758    }
759}
760
761impl<S> IntoInputValue<S> for i32
762where
763    i32: ToScalarValue<S>,
764{
765    fn into_input_value(self) -> InputValue<S> {
766        InputValue::Scalar(self.to_scalar_value())
767    }
768}
769
770impl<S> IntoInputValue<S> for f64
771where
772    f64: ToScalarValue<S>,
773{
774    fn into_input_value(self) -> InputValue<S> {
775        InputValue::Scalar(self.to_scalar_value())
776    }
777}
778
779impl<S> IntoInputValue<S> for bool
780where
781    bool: ToScalarValue<S>,
782{
783    fn into_input_value(self) -> InputValue<S> {
784        InputValue::Scalar(self.to_scalar_value())
785    }
786}
787
788impl<'a, S> Arguments<'a, S> {
789    pub fn into_iter(self) -> vec::IntoIter<(Spanning<&'a str>, Spanning<InputValue<S>>)> {
790        self.items.into_iter()
791    }
792
793    pub fn iter(&self) -> slice::Iter<'_, (Spanning<&'a str>, Spanning<InputValue<S>>)> {
794        self.items.iter()
795    }
796
797    pub fn iter_mut(&mut self) -> slice::IterMut<'_, (Spanning<&'a str>, Spanning<InputValue<S>>)> {
798        self.items.iter_mut()
799    }
800
801    pub fn len(&self) -> usize {
802        self.items.len()
803    }
804
805    pub fn get(&self, key: &str) -> Option<&Spanning<InputValue<S>>> {
806        self.items
807            .iter()
808            .filter(|&(k, _)| k.item == key)
809            .map(|(_, v)| v)
810            .next()
811    }
812}
813
814impl<'a, S> VariableDefinitions<'a, S> {
815    pub fn iter(&self) -> slice::Iter<'_, (Spanning<&'a str>, VariableDefinition<'a, S>)> {
816        self.items.iter()
817    }
818}
819
820#[cfg(test)]
821mod spec_input_value_fmt {
822    use crate::graphql_input_value;
823
824    use super::InputValue;
825
826    #[test]
827    fn correct() {
828        let value: InputValue = graphql_input_value!(null);
829        assert_eq!(value.to_string(), "null");
830
831        let value: InputValue = graphql_input_value!(123);
832        assert_eq!(value.to_string(), "123");
833
834        let value: InputValue = graphql_input_value!(12.3);
835        assert_eq!(value.to_string(), "12.3");
836
837        let value: InputValue = graphql_input_value!("FOO");
838        assert_eq!(value.to_string(), "\"FOO\"");
839
840        let value: InputValue = graphql_input_value!(true);
841        assert_eq!(value.to_string(), "true");
842
843        let value: InputValue = graphql_input_value!(BAR);
844        assert_eq!(value.to_string(), "BAR");
845
846        let value: InputValue = graphql_input_value!(@baz);
847        assert_eq!(value.to_string(), "$baz");
848
849        let value: InputValue = graphql_input_value!([1, 2]);
850        assert_eq!(value.to_string(), "[1, 2]");
851
852        let value: InputValue = graphql_input_value!({"foo": 1,"bar": 2});
853        assert_eq!(value.to_string(), "{foo: 1, bar: 2}");
854    }
855}