Fix using graphql_scalar proc macro inside a macro (#933)
This commit is contained in:
parent
92ad8b46ff
commit
d3896bd33c
2 changed files with 61 additions and 1 deletions
|
@ -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 }"#;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue