graphql_query/json/
conversion.rs

1use crate::ast::*;
2use serde_json::{Map as JSMap, Value as JSValue};
3
4/// Trait for convertin AST Value Nodes of a GraphQL language document to [serde_json::Value]s.
5pub trait ValueFromNode<'a>: Sized {
6    /// Convert current AST Value Node to a [serde_json::Value] with given [Variables].
7    fn to_json(self, variables: Option<&Variables<'a>>) -> JSValue;
8}
9
10impl<'a> ValueFromNode<'a> for Value<'a> {
11    #[inline]
12    fn to_json(self, variables: Option<&Variables<'a>>) -> JSValue {
13        match self {
14            Value::Variable(var) => var.to_json(variables),
15            Value::List(list) => list.to_json(variables),
16            Value::Object(obj) => obj.to_json(variables),
17            Value::Int(node) => node.to_json(variables),
18            Value::Float(node) => node.to_json(variables),
19            Value::Boolean(node) => node.to_json(variables),
20            Value::String(node) => node.to_json(variables),
21            Value::Enum(node) => node.to_json(variables),
22            Value::Null => JSValue::Null,
23        }
24    }
25}
26
27impl<'a> ValueFromNode<'a> for IntValue<'a> {
28    /// Convert current IntValue Node to a [serde_json::Value].
29    #[inline]
30    fn to_json(self, _variables: Option<&Variables<'a>>) -> JSValue {
31        let int = self.value.parse::<i32>();
32        match int {
33            Ok(value) => value.into(),
34            Err(_) => self.value.into(),
35        }
36    }
37}
38
39impl<'a> ValueFromNode<'a> for FloatValue<'a> {
40    /// Convert current FloatValue Node to a [serde_json::Value].
41    #[inline]
42    fn to_json(self, _variables: Option<&Variables<'a>>) -> JSValue {
43        let int = self.value.parse::<f64>();
44        match int {
45            Ok(value) => value.into(),
46            Err(_) => self.value.into(),
47        }
48    }
49}
50
51impl<'a> ValueFromNode<'a> for BooleanValue {
52    /// Convert current BooleanValue Node to a [serde_json::Value].
53    #[inline]
54    fn to_json(self, _variables: Option<&Variables<'a>>) -> JSValue {
55        self.value.into()
56    }
57}
58
59impl<'a> ValueFromNode<'a> for StringValue<'a> {
60    /// Convert current StringValue Node to a [serde_json::Value].
61    #[inline]
62    fn to_json(self, _variables: Option<&Variables<'a>>) -> JSValue {
63        self.value.into()
64    }
65}
66
67impl<'a> ValueFromNode<'a> for EnumValue<'a> {
68    /// Convert current EnumValue Node to a [serde_json::Value].
69    #[inline]
70    fn to_json(self, _variables: Option<&Variables<'a>>) -> JSValue {
71        self.value.into()
72    }
73}
74
75impl<'a> ValueFromNode<'a> for Variable<'a> {
76    /// Convert current Variable Node to a [serde_json::Value] with given [Variables].
77    #[inline]
78    fn to_json(self, variables: Option<&Variables<'a>>) -> JSValue {
79        variables
80            .and_then(|vars| vars.get(self.name))
81            .map(|value| value.clone().to_json(None))
82            .unwrap_or(JSValue::Null)
83    }
84}
85
86impl<'a> ValueFromNode<'a> for ListValue<'a> {
87    /// Convert current ListValue Node to a [serde_json::Value] with given [Variables].
88    #[inline]
89    fn to_json(self, variables: Option<&Variables<'a>>) -> JSValue {
90        self.into_iter()
91            .map(|value| value.to_json(variables))
92            .collect::<Vec<JSValue>>()
93            .into()
94    }
95}
96
97impl<'a> ValueFromNode<'a> for ObjectValue<'a> {
98    /// Convert current ObjectValue Node to a [serde_json::Value] with given [Variables].
99    #[inline]
100    fn to_json(self, variables: Option<&Variables<'a>>) -> JSValue {
101        self.into_iter()
102            .map(|field| (field.name.to_string(), field.value.to_json(variables)))
103            .collect::<JSMap<String, JSValue>>()
104            .into()
105    }
106}
107
108/// Convert AST Value Node to a [serde_json::Value] with given [Variables].
109pub fn value_from_ast_untyped<'a>(value: Value<'a>, variables: Option<&Variables<'a>>) -> JSValue {
110    value.to_json(variables)
111}