apollo_smith/
selection_set.rs1use crate::field::Field;
2use crate::fragment::FragmentSpread;
3use crate::fragment::InlineFragment;
4use crate::name::Name;
5use crate::DocumentBuilder;
6use apollo_compiler::ast;
7use apollo_compiler::Node;
8use arbitrary::Result as ArbitraryResult;
9
10#[derive(Debug, Clone)]
17pub struct SelectionSet {
18 selections: Vec<Selection>,
19}
20
21impl From<SelectionSet> for Vec<ast::Selection> {
22 fn from(sel_set: SelectionSet) -> Self {
23 sel_set.selections.into_iter().map(Into::into).collect()
24 }
25}
26
27impl TryFrom<apollo_parser::cst::SelectionSet> for SelectionSet {
28 type Error = crate::FromError;
29
30 fn try_from(selection_set: apollo_parser::cst::SelectionSet) -> Result<Self, Self::Error> {
31 Ok(Self {
32 selections: selection_set
33 .selections()
34 .map(Selection::try_from)
35 .collect::<Result<_, _>>()?,
36 })
37 }
38}
39
40#[derive(Debug, Clone)]
46pub enum Selection {
47 Field(Field),
49 FragmentSpread(FragmentSpread),
51 InlineFragment(InlineFragment),
53}
54
55impl From<Selection> for ast::Selection {
56 fn from(selection: Selection) -> Self {
57 match selection {
58 Selection::Field(field) => Self::Field(Node::new(field.into())),
59 Selection::FragmentSpread(fragment_spread) => {
60 Self::FragmentSpread(Node::new(fragment_spread.into()))
61 }
62 Selection::InlineFragment(inline_fragment) => {
63 Self::InlineFragment(Node::new(inline_fragment.into()))
64 }
65 }
66 }
67}
68
69impl TryFrom<apollo_parser::cst::Selection> for Selection {
70 type Error = crate::FromError;
71
72 fn try_from(selection: apollo_parser::cst::Selection) -> Result<Self, Self::Error> {
73 match selection {
74 apollo_parser::cst::Selection::Field(field) => field.try_into().map(Self::Field),
75 apollo_parser::cst::Selection::FragmentSpread(fragment_spread) => {
76 fragment_spread.try_into().map(Self::FragmentSpread)
77 }
78 apollo_parser::cst::Selection::InlineFragment(inline_fragment) => {
79 inline_fragment.try_into().map(Self::InlineFragment)
80 }
81 }
82 }
83}
84
85impl DocumentBuilder<'_> {
86 pub fn selection_set(&mut self) -> ArbitraryResult<SelectionSet> {
88 let mut exclude_names = Vec::new();
89 let selection_nb = self.stack.last().map(|o| o.fields_def().len()).unwrap_or(0);
90
91 let selections = (0..self.u.int_in_range(1..=5)?)
92 .map(|_| {
93 let index = self.u.int_in_range(0..=selection_nb)?;
94 self.selection(index, &mut exclude_names)
95 }) .collect::<ArbitraryResult<Vec<_>>>()?;
97 Ok(SelectionSet { selections })
98 }
99
100 pub fn selection(
102 &mut self,
103 index: usize,
104 excludes: &mut Vec<Name>,
105 ) -> ArbitraryResult<Selection> {
106 let selection = match self.u.int_in_range(0..=2usize)? {
107 0 => Selection::Field(self.field(index)?),
108 1 => match self.fragment_spread(excludes)? {
109 Some(frag_spread) => Selection::FragmentSpread(frag_spread),
110 None => Selection::Field(self.field(index)?),
111 },
112 2 => Selection::InlineFragment(self.inline_fragment()?),
113 _ => unreachable!(),
114 };
115
116 Ok(selection)
117 }
118}