Skip to content

Commit ac01b8e

Browse files
committed
Extend enum macro, improve test coverage
This adds description and deprecation support to the graphql_enum! macro, as well as extensive tests for all syntactical cases.
1 parent ac51f09 commit ac01b8e

File tree

4 files changed

+454
-15
lines changed

4 files changed

+454
-15
lines changed

src/macros/enums.rs

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,45 @@ you can write `graphql_enum!(Color as "MyColor" { ...`.
3535
macro_rules! graphql_enum {
3636
( @as_expr, $e:expr) => { $e };
3737
( @as_pattern, $p:pat) => { $p };
38+
( @as_path, $p:path) => { $p };
3839

39-
// EnumName as "__ExportedNmae" { Enum::Value => "STRING_VALUE", }
40-
// with no trailing comma
41-
( $name:path as $outname:tt { $($eval:path => $ename:tt),* }) => {
40+
// Calls $val.$func($arg) if $arg is not None
41+
( @maybe_apply, None, $func:ident, $val:expr ) => { $val };
42+
( @maybe_apply, $arg:tt, $func:ident, $val:expr ) => { $val.$func($arg) };
43+
44+
// Each of the @parse match arms accumulates data up to a call to @generate.
45+
//
46+
// ( $name, $outname, $descr ): the name of the Rust enum, the name of the
47+
// GraphQL enum (as a string), and the description of the enum (as a string or None)
48+
//
49+
// [ ( $eval, $ename, $edescr, $edepr ) , ] the value of the Rust enum,
50+
// the value of the GraphQL enum (as a string), the description of the enum
51+
// value (as a string or None), and the deprecation reason of the enum value
52+
// (as a string or None).
53+
(
54+
@generate,
55+
( $name:path, $outname:tt, $descr:tt ),
56+
[ $( ( $eval:tt, $ename:tt, $edescr:tt, $edepr:tt ) , )* ]
57+
) => {
4258
impl<CtxT> $crate::GraphQLType<CtxT> for $name {
4359
fn name() -> Option<&'static str> {
4460
Some(graphql_enum!(@as_expr, $outname))
4561
}
4662

4763
fn meta(registry: &mut $crate::Registry<CtxT>) -> $crate::meta::MetaType {
48-
registry.build_enum_type::<$name>()(&[
49-
$( $crate::meta::EnumValue::new(graphql_enum!(@as_expr, $ename)) ),*
50-
])
64+
graphql_enum!(
65+
@maybe_apply, $descr, description,
66+
registry.build_enum_type::<$name>()(&[
67+
$(
68+
graphql_enum!(
69+
@maybe_apply,
70+
$edepr, deprecated,
71+
graphql_enum!(
72+
@maybe_apply,
73+
$edescr, description,
74+
$crate::meta::EnumValue::new(graphql_enum!(@as_expr, $ename))))
75+
),*
76+
]))
5177
.into_meta()
5278
}
5379

@@ -82,18 +108,79 @@ macro_rules! graphql_enum {
82108
}
83109
};
84110

85-
// Same as above, *with* trailing comma
86-
( $name:path as $outname:tt { $($eval:path => $ename:tt, )* }) => {
87-
graphql_enum!($name as $outname { $( $eval => $ename ),* });
111+
// No more items to parse
112+
( @parse, $meta:tt, $acc:tt, ) => {
113+
graphql_enum!( @generate, $meta, $acc );
114+
};
115+
116+
// Remove extraneous commas
117+
( @parse, $meta:tt, $acc:tt, , $($rest:tt)* ) => {
118+
graphql_enum!( @parse, $meta, $acc, $($rest)* );
119+
};
120+
121+
// description: <description>
122+
(
123+
@parse,
124+
( $name:tt, $outname:tt, $_ignore:tt ),
125+
$acc:tt,
126+
description: $descr:tt $($items:tt)*
127+
) => {
128+
graphql_enum!( @parse, ( $name, $outname, $descr ), $acc, $($items)* );
129+
};
130+
131+
// RustEnumValue => "GraphQL enum value" deprecated <reason>
132+
(
133+
@parse,
134+
$meta:tt,
135+
[ $($acc:tt ,)* ],
136+
$eval:path => $ename:tt deprecated $depr:tt $($rest:tt)*
137+
) => {
138+
graphql_enum!( @parse, $meta, [ $($acc ,)* ( $eval, $ename, None, $depr ), ], $($rest)* );
139+
};
140+
141+
// RustEnumValue => "GraphQL enum value" as <description> deprecated <reason>
142+
(
143+
@parse,
144+
$meta:tt,
145+
[ $($acc:tt ,)* ],
146+
$eval:path => $ename:tt as $descr:tt deprecated $depr:tt $($rest:tt)*
147+
) => {
148+
graphql_enum!( @parse, $meta, [ $($acc ,)* ( $eval, $ename, $descr, $depr ), ], $($rest)* );
149+
};
150+
151+
// RustEnumValue => "GraphQL enum value" as <description>
152+
(
153+
@parse,
154+
$meta:tt,
155+
[ $($acc:tt ,)* ],
156+
$eval:path => $ename:tt as $descr:tt $($rest:tt)*
157+
) => {
158+
graphql_enum!( @parse, $meta, [ $($acc ,)* ( $eval, $ename, $descr, None ), ], $($rest)* );
159+
};
160+
161+
// RustEnumValue => "GraphQL enum value"
162+
(
163+
@parse,
164+
$meta:tt,
165+
[ $($acc:tt ,)* ],
166+
$eval:path => $ename:tt $($rest:tt)*
167+
) => {
168+
graphql_enum!( @parse, $meta, [ $($acc ,)* ( $eval , $ename , None , None ), ], $($rest)* );
88169
};
89170

90-
// Default named enum, without trailing comma
91-
( $name:path { $($eval:path => $ename:tt),* }) => {
92-
graphql_enum!($name as (stringify!($name)) { $( $eval => $ename ),* });
171+
// Entry point:
172+
// RustEnumName as "GraphQLEnumName" { ... }
173+
(
174+
$name:path as $outname:tt { $($items:tt)* }
175+
) => {
176+
graphql_enum!( @parse, ( $name, $outname, None ), [ ], $($items)* );
93177
};
94178

95-
// Default named enum, with trailing comma
96-
( $name:path { $($eval:path => $ename:tt, )* }) => {
97-
graphql_enum!($name as (stringify!($name)) { $( $eval => $ename ),* });
179+
// Entry point
180+
// RustEnumName { ... }
181+
(
182+
$name:path { $($items:tt)* }
183+
) => {
184+
graphql_enum!( @parse, ( $name, (stringify!($name)), None ), [ ], $($items)* );
98185
};
99186
}

src/macros/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
#[macro_use] mod scalar;
55
#[macro_use] mod args;
66
#[macro_use] mod field;
7+
8+
#[cfg(test)] mod tests;

0 commit comments

Comments
 (0)