apollo_encoder/
scalar_def.rs

1use std::fmt;
2
3use crate::{Directive, StringValue};
4/// Represents scalar types such as Int, String, and Boolean.
5/// Scalars cannot have fields.
6///
7/// *ScalarTypeDefinition*:
8///     Description? **scalar** Name Directives?
9///
10/// Detailed documentation can be found in [GraphQL spec](https://spec.graphql.org/October2021/#sec-Scalar).
11/// ### Example
12/// ```rust
13/// use apollo_encoder::ScalarDefinition;
14///
15/// let mut scalar = ScalarDefinition::new("NumberOfTreatsPerDay".to_string());
16/// scalar.description(
17///     "Int representing number of treats received.".to_string(),
18/// );
19///
20/// assert_eq!(
21///     scalar.to_string(),
22///     r#""Int representing number of treats received."
23/// scalar NumberOfTreatsPerDay
24/// "#
25/// );
26/// ```
27#[derive(Debug, PartialEq, Clone)]
28pub struct ScalarDefinition {
29    // Name must return a String.
30    name: String,
31    // Description may return a String or null.
32    description: Option<StringValue>,
33    directives: Vec<Directive>,
34    extend: bool,
35}
36
37impl ScalarDefinition {
38    /// Create a new instance of Scalar Definition.
39    pub fn new(name: String) -> Self {
40        Self {
41            name,
42            description: None,
43            directives: Vec::new(),
44            extend: false,
45        }
46    }
47
48    /// Set the ScalarDef's description.
49    pub fn description(&mut self, description: String) {
50        self.description = Some(StringValue::Top {
51            source: description,
52        });
53    }
54
55    /// Add a directive.
56    pub fn directive(&mut self, directive: Directive) {
57        self.directives.push(directive);
58    }
59
60    /// Set the scalar as an extension
61    pub fn extend(&mut self) {
62        self.extend = true;
63    }
64}
65
66impl fmt::Display for ScalarDefinition {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        if self.extend {
69            write!(f, "extend ")?;
70        } else if let Some(description) = &self.description {
71            writeln!(f, "{description}")?;
72        }
73
74        write!(f, "scalar {}", self.name)?;
75        for directive in &self.directives {
76            write!(f, " {directive}")?;
77        }
78        writeln!(f)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84
85    use crate::{Argument, Value};
86
87    use super::*;
88    use pretty_assertions::assert_eq;
89
90    #[test]
91    fn it_encodes_scalar() {
92        let scalar = ScalarDefinition::new("NumberOfTreatsPerDay".to_string());
93        assert_eq!(
94            scalar.to_string(),
95            r#"scalar NumberOfTreatsPerDay
96"#
97        );
98    }
99
100    #[test]
101    fn it_encodes_scalar_with_description() {
102        let mut scalar = ScalarDefinition::new("NumberOfTreatsPerDay".to_string());
103        scalar.description("Int representing number of treats received.".to_string());
104
105        assert_eq!(
106            scalar.to_string(),
107            r#""Int representing number of treats received."
108scalar NumberOfTreatsPerDay
109"#
110        );
111    }
112
113    #[test]
114    fn it_encodes_scalar_with_extend_directive() {
115        let mut scalar = ScalarDefinition::new("NumberOfTreatsPerDay".to_string());
116        scalar.description("Int representing number of treats received.".to_string());
117        scalar.extend();
118        let mut directive = Directive::new(String::from("tag"));
119        directive.arg(Argument::new(
120            String::from("name"),
121            Value::String("team-admin".to_string()),
122        ));
123        scalar.directive(directive);
124
125        assert_eq!(
126            scalar.to_string(),
127            r#"extend scalar NumberOfTreatsPerDay @tag(name: "team-admin")
128"#
129        );
130    }
131}