use std::fmt;
use crate::{Directive, StringValue, Type_};
#[derive(Debug, PartialEq, Clone)]
pub struct InputValueDefinition {
name: String,
pub(crate) description: Option<StringValue>,
type_: Type_,
default_value: Option<String>,
directives: Vec<Directive>,
}
impl InputValueDefinition {
pub fn new(name: String, type_: Type_) -> Self {
Self {
description: None,
name,
type_,
default_value: None,
directives: Vec::new(),
}
}
pub fn description(&mut self, description: String) {
self.description = Some(StringValue::Input {
source: description,
});
}
pub fn default_value(&mut self, default_value: String) {
self.default_value = Some(default_value);
}
pub fn directive(&mut self, directive: Directive) {
self.directives.push(directive)
}
}
impl fmt::Display for InputValueDefinition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.description {
Some(description) => {
writeln!(f, "\n{description}")?;
write!(f, " {}: {}", self.name, self.type_)?;
}
None => {
write!(f, "{}: {}", self.name, self.type_)?;
}
}
if let Some(default) = &self.default_value {
write!(f, " = {default}")?;
}
for directive in &self.directives {
write!(f, " {directive}")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use crate::{Argument, Value};
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn it_encodes_simple_values() {
let ty_1 = Type_::NamedType {
name: "SpaceProgram".to_string(),
};
let ty_2 = Type_::List { ty: Box::new(ty_1) };
let ty_3 = Type_::NonNull { ty: Box::new(ty_2) };
let value = InputValueDefinition::new("spaceCat".to_string(), ty_3);
assert_eq!(value.to_string(), r#"spaceCat: [SpaceProgram]!"#);
}
#[test]
fn it_encodes_input_values_with_default() {
let ty_1 = Type_::NamedType {
name: "Breed".to_string(),
};
let ty_2 = Type_::NonNull { ty: Box::new(ty_1) };
let mut value = InputValueDefinition::new("spaceCat".to_string(), ty_2);
value.default_value("\"Norwegian Forest\"".to_string());
assert_eq!(
value.to_string(),
r#"spaceCat: Breed! = "Norwegian Forest""#
);
}
#[test]
fn it_encodes_value_with_directive() {
let ty_1 = Type_::NamedType {
name: "SpaceProgram".to_string(),
};
let ty_2 = Type_::List { ty: Box::new(ty_1) };
let mut value = InputValueDefinition::new("cat".to_string(), ty_2);
let mut directive = Directive::new(String::from("testDirective"));
directive.arg(Argument::new(String::from("first"), Value::Int(1)));
value.description("Very good cats".to_string());
value.directive(directive);
assert_eq!(
value.to_string(),
r#"
"Very good cats"
cat: [SpaceProgram] @testDirective(first: 1)"#
);
}
#[test]
fn it_encodes_valueuments_with_description() {
let ty_1 = Type_::NamedType {
name: "SpaceProgram".to_string(),
};
let ty_2 = Type_::NonNull { ty: Box::new(ty_1) };
let ty_3 = Type_::List { ty: Box::new(ty_2) };
let ty_4 = Type_::NonNull { ty: Box::new(ty_3) };
let mut value = InputValueDefinition::new("spaceCat".to_string(), ty_4);
value.description("Very good space cats".to_string());
assert_eq!(
value.to_string(),
r#"
"Very good space cats"
spaceCat: [SpaceProgram!]!"#
);
}
}