Skip to content

Commit d3896bd

Browse files
authored
Fix using graphql_scalar proc macro inside a macro (#933)
1 parent 92ad8b4 commit d3896bd

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

integration_tests/juniper_tests/src/codegen/impl_scalar.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct DefaultName(i32);
99
struct OtherOrder(i32);
1010
struct Named(i32);
1111
struct ScalarDescription(i32);
12+
struct Generated(String);
1213

1314
struct Root;
1415

@@ -86,6 +87,32 @@ impl GraphQLScalar for ScalarDescription {
8687
}
8788
}
8889

90+
macro_rules! impl_scalar {
91+
($name: ident) => {
92+
#[graphql_scalar]
93+
impl<S> GraphQLScalar for $name
94+
where
95+
S: ScalarValue,
96+
{
97+
fn resolve(&self) -> Value {
98+
Value::scalar(self.0.clone())
99+
}
100+
101+
fn from_input_value(v: &InputValue) -> Option<Self> {
102+
v.as_scalar_value()
103+
.and_then(|v| v.as_str())
104+
.and_then(|s| Some(Self(s.to_owned())))
105+
}
106+
107+
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> {
108+
<String as ParseScalarValue<S>>::from_str(value)
109+
}
110+
}
111+
};
112+
}
113+
114+
impl_scalar!(Generated);
115+
89116
#[graphql_object(scalar = DefaultScalarValue)]
90117
impl Root {
91118
fn default_name() -> DefaultName {
@@ -100,6 +127,9 @@ impl Root {
100127
fn scalar_description() -> ScalarDescription {
101128
ScalarDescription(0)
102129
}
130+
fn generated() -> Generated {
131+
Generated("foo".to_owned())
132+
}
103133
}
104134

105135
struct WithCustomScalarValue(i32);
@@ -274,6 +304,30 @@ async fn scalar_description_introspection() {
274304
.await;
275305
}
276306

307+
#[tokio::test]
308+
async fn generated_scalar_introspection() {
309+
let doc = r#"
310+
{
311+
__type(name: "Generated") {
312+
name
313+
description
314+
}
315+
}
316+
"#;
317+
318+
run_type_info_query(doc, |type_info| {
319+
assert_eq!(
320+
type_info.get_field_value("name"),
321+
Some(&Value::scalar("Generated"))
322+
);
323+
assert_eq!(
324+
type_info.get_field_value("description"),
325+
Some(&Value::null())
326+
);
327+
})
328+
.await;
329+
}
330+
277331
#[tokio::test]
278332
async fn resolves_with_custom_scalar_value() {
279333
const DOC: &str = r#"{ withCustomScalarValue }"#;

juniper_codegen/src/impl_scalar.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ impl syn::parse::Parse for ScalarCodegenInput {
8888
let custom_data_type_is_struct: bool =
8989
!parse_custom_scalar_value_impl.generics.params.is_empty();
9090

91-
if let syn::Type::Path(type_path) = *parse_custom_scalar_value_impl.self_ty {
91+
let mut self_ty = *parse_custom_scalar_value_impl.self_ty;
92+
93+
while let syn::Type::Group(type_group) = self_ty {
94+
self_ty = *type_group.elem;
95+
}
96+
97+
if let syn::Type::Path(type_path) = self_ty {
9298
if let Some(path_segment) = type_path.path.segments.first() {
9399
impl_for_type = Some(path_segment.clone());
94100
}

0 commit comments

Comments
 (0)