1use crate::description::Description;
2use crate::directive::Directive;
3use crate::directive::DirectiveLocation;
4use crate::input_value::InputValue;
5use crate::name::Name;
6use crate::ty::Ty;
7use crate::DocumentBuilder;
8use apollo_compiler::ast;
9use apollo_compiler::Node;
10use arbitrary::Result as ArbitraryResult;
11use indexmap::IndexMap;
12
13#[derive(Debug, Clone)]
20pub struct VariableDef {
21 description: Option<Description>,
22 name: Name,
23 ty: Ty,
24 default_value: Option<InputValue>,
25 directives: IndexMap<Name, Directive>,
26}
27
28impl From<VariableDef> for ast::VariableDefinition {
29 fn from(x: VariableDef) -> Self {
30 Self {
31 description: x.description.map(Into::into),
32 name: x.name.into(),
33 ty: Node::new(x.ty.into()),
34 default_value: x.default_value.map(|x| Node::new(x.into())),
35 directives: Directive::to_ast(x.directives),
36 }
37 }
38}
39
40impl DocumentBuilder<'_> {
41 pub fn variable_definitions(&mut self) -> ArbitraryResult<Vec<VariableDef>> {
43 (0..self.u.int_in_range(0..=7usize)?)
44 .map(|_| self.variable_definition()) .collect()
46 }
47
48 pub fn variable_definition(&mut self) -> ArbitraryResult<VariableDef> {
50 let name = self.type_name()?;
51 let ty = self.choose_ty(&self.list_existing_input_types())?;
52 let default_value = self
53 .u
54 .arbitrary()
55 .unwrap_or(false)
56 .then(|| self.input_value_for_type(&ty))
57 .transpose()?;
58 let directives = self.directives(DirectiveLocation::VariableDefinition)?;
59
60 Ok(VariableDef {
61 description: None,
62 name,
63 ty,
64 default_value,
65 directives,
66 })
67 }
68}