Fix using graphql_scalar proc macro inside a macro (#933)

This commit is contained in:
ihor-rud 2021-06-07 00:05:53 +02:00 committed by GitHub
parent 92ad8b46ff
commit d3896bd33c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 1 deletions

View file

@ -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<S> GraphQLScalar for $name
where
S: ScalarValue,
{
fn resolve(&self) -> Value {
Value::scalar(self.0.clone())
}
fn from_input_value(v: &InputValue) -> Option<Self> {
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> {
<String as ParseScalarValue<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 }"#;

View file

@ -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());
}