diff --git a/integration_tests/juniper_tests/src/codegen/impl_scalar.rs b/integration_tests/juniper_tests/src/codegen/impl_scalar.rs index 721aba8f..9da7de8e 100644 --- a/integration_tests/juniper_tests/src/codegen/impl_scalar.rs +++ b/integration_tests/juniper_tests/src/codegen/impl_scalar.rs @@ -9,6 +9,7 @@ struct DefaultName(i32); struct OtherOrder(i32); struct Named(i32); struct ScalarDescription(i32); +struct Generated(String); struct Root; @@ -86,6 +87,32 @@ impl GraphQLScalar for ScalarDescription { } } +macro_rules! impl_scalar { + ($name: ident) => { + #[graphql_scalar] + impl GraphQLScalar for $name + where + S: ScalarValue, + { + fn resolve(&self) -> Value { + Value::scalar(self.0.clone()) + } + + fn from_input_value(v: &InputValue) -> Option { + v.as_scalar_value() + .and_then(|v| v.as_str()) + .and_then(|s| Some(Self(s.to_owned()))) + } + + fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> { + >::from_str(value) + } + } + }; +} + +impl_scalar!(Generated); + #[graphql_object(scalar = DefaultScalarValue)] impl Root { fn default_name() -> DefaultName { @@ -100,6 +127,9 @@ impl Root { fn scalar_description() -> ScalarDescription { ScalarDescription(0) } + fn generated() -> Generated { + Generated("foo".to_owned()) + } } struct WithCustomScalarValue(i32); @@ -274,6 +304,30 @@ async fn scalar_description_introspection() { .await; } +#[tokio::test] +async fn generated_scalar_introspection() { + let doc = r#" + { + __type(name: "Generated") { + name + description + } + } + "#; + + run_type_info_query(doc, |type_info| { + assert_eq!( + type_info.get_field_value("name"), + Some(&Value::scalar("Generated")) + ); + assert_eq!( + type_info.get_field_value("description"), + Some(&Value::null()) + ); + }) + .await; +} + #[tokio::test] async fn resolves_with_custom_scalar_value() { const DOC: &str = r#"{ withCustomScalarValue }"#; diff --git a/juniper_codegen/src/impl_scalar.rs b/juniper_codegen/src/impl_scalar.rs index 9d828df8..8109f147 100644 --- a/juniper_codegen/src/impl_scalar.rs +++ b/juniper_codegen/src/impl_scalar.rs @@ -88,7 +88,13 @@ impl syn::parse::Parse for ScalarCodegenInput { let custom_data_type_is_struct: bool = !parse_custom_scalar_value_impl.generics.params.is_empty(); - if let syn::Type::Path(type_path) = *parse_custom_scalar_value_impl.self_ty { + let mut self_ty = *parse_custom_scalar_value_impl.self_ty; + + while let syn::Type::Group(type_group) = self_ty { + self_ty = *type_group.elem; + } + + if let syn::Type::Path(type_path) = self_ty { if let Some(path_segment) = type_path.path.segments.first() { impl_for_type = Some(path_segment.clone()); }