apollo_encoder/
variable.rs

1use std::fmt;
2
3use crate::{Directive, Type_, Value};
4
5/// The VariableDefinition type represents a variable definition
6///
7/// *VariableDefinition*:
8///     VariableName : Type DefaultValue? Directives?
9///
10/// Detailed documentation can be found in [GraphQL spec](https://spec.graphql.org/October2021/#sec-Language.Variables).
11///
12/// ### Example
13/// ```rust
14/// use apollo_encoder::{Type_, Value, VariableDefinition};
15///
16/// let mut variable = VariableDefinition::new(
17///     String::from("my_var"),
18///     Type_::NamedType {
19///         name: String::from("MyType"),
20///     },
21/// );
22/// variable.default_value(Value::Object(vec![
23///     (String::from("first"), Value::Int(25)),
24///     (String::from("second"), Value::String(String::from("test"))),
25/// ]));
26///
27/// assert_eq!(
28///     variable.to_string(),
29///     String::from(r#"$my_var: MyType = { first: 25, second: "test" }"#)
30/// );
31/// ```
32#[derive(Debug, Clone)]
33pub struct VariableDefinition {
34    variable: String,
35    ty: Type_,
36    default_value: Option<Value>,
37    directives: Vec<Directive>,
38}
39
40impl VariableDefinition {
41    /// Create an instance of VariableDefinition
42    pub fn new(variable: String, ty: Type_) -> Self {
43        Self {
44            variable,
45            ty,
46            default_value: Option::default(),
47            directives: Vec::new(),
48        }
49    }
50
51    /// Set a default value to the variable
52    pub fn default_value(&mut self, default_value: Value) {
53        self.default_value = Some(default_value);
54    }
55
56    /// Add a directive
57    pub fn directive(&mut self, directive: Directive) {
58        self.directives.push(directive);
59    }
60}
61
62impl fmt::Display for VariableDefinition {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "${}: {}", self.variable, self.ty)?;
65
66        if let Some(default_value) = &self.default_value {
67            write!(f, " = {default_value}")?;
68        }
69
70        for directive in &self.directives {
71            write!(f, " {directive}")?;
72        }
73
74        Ok(())
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn it_encodes_variable_definition() {
84        let mut variable = VariableDefinition::new(
85            String::from("my_var"),
86            Type_::NamedType {
87                name: String::from("MyType"),
88            },
89        );
90        variable.default_value(Value::Object(vec![
91            (String::from("first"), Value::Int(25)),
92            (String::from("second"), Value::String(String::from("test"))),
93        ]));
94
95        assert_eq!(
96            variable.to_string(),
97            String::from(r#"$my_var: MyType = { first: 25, second: "test" }"#)
98        );
99    }
100}