Skip to content

Commit b08c67c

Browse files
committed
fragment variables
1 parent 1340772 commit b08c67c

File tree

6 files changed

+74
-12
lines changed

6 files changed

+74
-12
lines changed

src/query/ast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub enum Definition<'a, T: Text<'a>> {
4343
pub struct FragmentDefinition<'a, T: Text<'a>> {
4444
pub position: Pos,
4545
pub name: T::Value,
46+
pub variable_definitions: Vec<VariableDefinition<'a, T>>,
4647
pub type_condition: TypeCondition<'a, T>,
4748
pub directives: Vec<Directive<'a, T>>,
4849
pub selection_set: SelectionSet<'a, T>,
@@ -118,6 +119,7 @@ pub struct Field<'a, T: Text<'a>> {
118119
pub struct FragmentSpread<'a, T: Text<'a>> {
119120
pub position: Pos,
120121
pub fragment_name: T::Value,
122+
pub arguments: Vec<(T::Value, Value<'a, T>)>,
121123
pub directives: Vec<Directive<'a, T>>,
122124
}
123125

src/query/format.rs

+10
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ impl<'a, T: Text<'a>> Displayable for FragmentDefinition<'a, T> {
5454
f.indent();
5555
f.write("fragment ");
5656
f.write(self.name.as_ref());
57+
if !self.variable_definitions.is_empty() {
58+
f.write("(");
59+
self.variable_definitions[0].display(f);
60+
for var in &self.variable_definitions[1..] {
61+
f.write(", ");
62+
var.display(f);
63+
}
64+
f.write(")");
65+
}
5766
f.write(" ");
5867
self.type_condition.display(f);
5968
format_directives(&self.directives, f);
@@ -322,6 +331,7 @@ impl<'a, T: Text<'a>> Displayable for FragmentSpread<'a, T> {
322331
f.indent();
323332
f.write("...");
324333
f.write(self.fragment_name.as_ref());
334+
format_arguments(&self.arguments, f);
325335
format_directives(&self.directives, f);
326336
f.endline();
327337
}

src/query/grammar.rs

+44-12
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,20 @@ where
6767
},
6868
)
6969
.map(Selection::InlineFragment)
70-
.or((position(), name::<'a, S>(), parser(directives))
71-
.map(|(position, fragment_name, directives)| FragmentSpread {
72-
position,
73-
fragment_name,
74-
directives,
75-
})
70+
.or((
71+
position(),
72+
name::<'a, S>(),
73+
parser(arguments),
74+
parser(directives),
75+
)
76+
.map(
77+
|(position, fragment_name, arguments, directives)| FragmentSpread {
78+
position,
79+
fragment_name,
80+
arguments,
81+
directives,
82+
},
83+
)
7684
.map(Selection::FragmentSpread)),
7785
))
7886
.parse_stream(input)
@@ -219,17 +227,41 @@ pub fn fragment_definition<'a, T: Text<'a>>(
219227
(
220228
position().skip(ident("fragment")),
221229
name::<'a, T>(),
230+
optional(
231+
punct("(")
232+
.with(many1(
233+
(
234+
position(),
235+
punct("$").with(name::<'a, T>()).skip(punct(":")),
236+
parser(parse_type),
237+
optional(punct("=").with(parser(default_value))),
238+
)
239+
.map(|(position, name, var_type, default_value)| {
240+
VariableDefinition {
241+
position,
242+
name,
243+
var_type,
244+
default_value,
245+
}
246+
}),
247+
))
248+
.skip(punct(")")),
249+
)
250+
.map(|vars| vars.unwrap_or_default()),
222251
ident("on").with(name::<'a, T>()).map(TypeCondition::On),
223252
parser(directives),
224253
parser(selection_set),
225254
)
226255
.map(
227-
|(position, name, type_condition, directives, selection_set)| FragmentDefinition {
228-
position,
229-
name,
230-
type_condition,
231-
directives,
232-
selection_set,
256+
|(position, name, variable_definitions, type_condition, directives, selection_set)| {
257+
FragmentDefinition {
258+
position,
259+
name,
260+
variable_definitions,
261+
type_condition,
262+
directives,
263+
selection_set,
264+
}
233265
},
234266
)
235267
.parse_stream(input)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
query {
2+
node {
3+
id
4+
...something(arg: "test")
5+
...somethingElse(arg2: $var)
6+
}
7+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fragment frag($arg: String!) on Friend {
2+
node
3+
}

tests/query_roundtrips.rs

+8
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ fn fragment_spread() {
152152
roundtrip_default("fragment_spread");
153153
}
154154
#[test]
155+
fn fragment_spread_arguments() {
156+
roundtrip_default("fragment_spread_arguments");
157+
}
158+
#[test]
155159
fn minimal_mutation() {
156160
roundtrip_default("minimal_mutation");
157161
}
@@ -160,6 +164,10 @@ fn fragment() {
160164
roundtrip_default("fragment");
161165
}
162166
#[test]
167+
fn fragment_variables() {
168+
roundtrip_default("fragment_variables");
169+
}
170+
#[test]
163171
fn directive_args() {
164172
roundtrip_default("directive_args");
165173
}

0 commit comments

Comments
 (0)