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 OtherOrder(i32);
|
||||||
struct Named(i32);
|
struct Named(i32);
|
||||||
struct ScalarDescription(i32);
|
struct ScalarDescription(i32);
|
||||||
|
struct Generated(String);
|
||||||
|
|
||||||
struct Root;
|
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)]
|
#[graphql_object(scalar = DefaultScalarValue)]
|
||||||
impl Root {
|
impl Root {
|
||||||
fn default_name() -> DefaultName {
|
fn default_name() -> DefaultName {
|
||||||
|
@ -100,6 +127,9 @@ impl Root {
|
||||||
fn scalar_description() -> ScalarDescription {
|
fn scalar_description() -> ScalarDescription {
|
||||||
ScalarDescription(0)
|
ScalarDescription(0)
|
||||||
}
|
}
|
||||||
|
fn generated() -> Generated {
|
||||||
|
Generated("foo".to_owned())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WithCustomScalarValue(i32);
|
struct WithCustomScalarValue(i32);
|
||||||
|
@ -274,6 +304,30 @@ async fn scalar_description_introspection() {
|
||||||
.await;
|
.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]
|
#[tokio::test]
|
||||||
async fn resolves_with_custom_scalar_value() {
|
async fn resolves_with_custom_scalar_value() {
|
||||||
const DOC: &str = r#"{ withCustomScalarValue }"#;
|
const DOC: &str = r#"{ withCustomScalarValue }"#;
|
||||||
|
|
|
@ -88,7 +88,13 @@ impl syn::parse::Parse for ScalarCodegenInput {
|
||||||
let custom_data_type_is_struct: bool =
|
let custom_data_type_is_struct: bool =
|
||||||
!parse_custom_scalar_value_impl.generics.params.is_empty();
|
!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() {
|
if let Some(path_segment) = type_path.path.segments.first() {
|
||||||
impl_for_type = Some(path_segment.clone());
|
impl_for_type = Some(path_segment.clone());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue