Specified By - [GraphQL - October 2021] #677
This commit is contained in:
parent
38dcc7d582
commit
c6d26884a9
|
@ -446,6 +446,7 @@ pub struct Scalar {
|
|||
pub name: Option<String>,
|
||||
pub use_type_description: bool,
|
||||
pub visible: Option<Visible>,
|
||||
pub specified_by_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(FromMeta, Default)]
|
||||
|
@ -652,6 +653,8 @@ pub struct NewType {
|
|||
pub name: NewTypeName,
|
||||
#[darling(default)]
|
||||
pub visible: Option<Visible>,
|
||||
#[darling(default)]
|
||||
pub specified_by_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(FromMeta, Default)]
|
||||
|
|
|
@ -38,12 +38,18 @@ pub fn generate(newtype_args: &args::NewType) -> GeneratorResult<TokenStream> {
|
|||
None => quote! { <#inner_ty as #crate_name::Type>::type_name() },
|
||||
};
|
||||
let create_type_info = if let Some(name) = &gql_typename {
|
||||
let specified_by_url = match &newtype_args.specified_by_url {
|
||||
Some(specified_by_url) => quote! { ::std::option::Option::Some(#specified_by_url) },
|
||||
None => quote! { ::std::option::Option::None },
|
||||
};
|
||||
|
||||
quote! {
|
||||
registry.create_type::<#ident, _>(|_| #crate_name::registry::MetaType::Scalar {
|
||||
name: ::std::borrow::ToOwned::to_owned(#name),
|
||||
description: #desc,
|
||||
is_valid: |value| <#ident as #crate_name::ScalarType>::is_valid(value),
|
||||
visible: #visible,
|
||||
specified_by_url: #specified_by_url,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,11 @@ pub fn generate(
|
|||
let generic = &item_impl.generics;
|
||||
let where_clause = &item_impl.generics.where_clause;
|
||||
let visible = visible_fn(&scalar_args.visible);
|
||||
let specified_by_url = match &scalar_args.specified_by_url {
|
||||
Some(specified_by_url) => quote! { ::std::option::Option::Some(#specified_by_url) },
|
||||
None => quote! { ::std::option::Option::None },
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
#item_impl
|
||||
|
||||
|
@ -45,6 +50,7 @@ pub fn generate(
|
|||
description: #desc,
|
||||
is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value),
|
||||
visible: #visible,
|
||||
specified_by_url: #specified_by_url,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -987,6 +987,7 @@ pub use async_graphql_derive::Subscription;
|
|||
/// | Attribute | description | Type | Optional |
|
||||
/// |-------------|---------------------------|----------|----------|
|
||||
/// | name | Scalar name | string | Y |
|
||||
/// | specified_by_url | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
///
|
||||
pub use async_graphql_derive::Scalar;
|
||||
|
||||
|
@ -1000,8 +1001,9 @@ pub use async_graphql_derive::Scalar;
|
|||
/// |-------------|---------------------------|----------|----------|
|
||||
/// | name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | string | Y |
|
||||
/// | name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | bool | Y |
|
||||
/// | visible(Only valid for new scalars.) | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
/// | visible(Only valid for new scalars.) | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
/// | visible(Only valid for new scalars) | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
/// | visible(Only valid for new scalars) | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
/// | specified_by_url(Only valid for new scalars) | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -218,4 +218,16 @@ impl<'a> __Type<'a> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[graphql(name = "specifiedByURL")]
|
||||
async fn specified_by_url(&self) -> Option<&'a str> {
|
||||
if let TypeDetail::Named(registry::MetaType::Scalar {
|
||||
specified_by_url, ..
|
||||
}) = &self.detail
|
||||
{
|
||||
*specified_by_url
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,6 +189,7 @@ pub enum MetaType {
|
|||
description: Option<&'static str>,
|
||||
is_valid: fn(value: &Value) -> bool,
|
||||
visible: Option<MetaVisibleFn>,
|
||||
specified_by_url: Option<&'static str>,
|
||||
},
|
||||
Object {
|
||||
name: String,
|
||||
|
|
|
@ -68,6 +68,9 @@ pub trait ScalarType: Sized + Send {
|
|||
/// // Rename to `MV` and add description.
|
||||
/// // scalar!(MyValue, "MV", "This is my value");
|
||||
///
|
||||
/// // Rename to `MV`, add description and specifiedByURL.
|
||||
/// // scalar!(MyValue, "MV", "This is my value", "https://tools.ietf.org/html/rfc4122");
|
||||
///
|
||||
/// struct Query;
|
||||
///
|
||||
/// #[Object]
|
||||
|
@ -92,23 +95,47 @@ pub trait ScalarType: Sized + Send {
|
|||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! scalar {
|
||||
($ty:ty, $name:literal, $desc:literal, $specified_by_url:literal) => {
|
||||
$crate::scalar_internal!(
|
||||
$ty,
|
||||
$name,
|
||||
::std::option::Option::Some($desc),
|
||||
::std::option::Option::Some($specified_by_url)
|
||||
);
|
||||
};
|
||||
|
||||
($ty:ty, $name:literal, $desc:literal) => {
|
||||
$crate::scalar_internal!($ty, $name, ::std::option::Option::Some($desc));
|
||||
$crate::scalar_internal!(
|
||||
$ty,
|
||||
$name,
|
||||
::std::option::Option::Some($desc),
|
||||
::std::option::Option::None
|
||||
);
|
||||
};
|
||||
|
||||
($ty:ty, $name:literal) => {
|
||||
$crate::scalar_internal!($ty, $name, ::std::option::Option::None);
|
||||
$crate::scalar_internal!(
|
||||
$ty,
|
||||
$name,
|
||||
::std::option::Option::None,
|
||||
::std::option::Option::None
|
||||
);
|
||||
};
|
||||
|
||||
($ty:ty) => {
|
||||
$crate::scalar_internal!($ty, ::std::stringify!($ty), ::std::option::Option::None);
|
||||
$crate::scalar_internal!(
|
||||
$ty,
|
||||
::std::stringify!($ty),
|
||||
::std::option::Option::None,
|
||||
::std::option::Option::None
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! scalar_internal {
|
||||
($ty:ty, $name:expr, $desc:expr) => {
|
||||
($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
|
||||
impl $crate::Type for $ty {
|
||||
fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
|
||||
::std::borrow::Cow::Borrowed($name)
|
||||
|
@ -122,6 +149,7 @@ macro_rules! scalar_internal {
|
|||
description: $desc,
|
||||
is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value),
|
||||
visible: ::std::option::Option::None,
|
||||
specified_by_url: $specified_by_url,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ impl<T> Type for OutputJson<T> {
|
|||
description: None,
|
||||
is_valid: |_| true,
|
||||
visible: None,
|
||||
specified_by_url: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ impl Type for Upload {
|
|||
description: None,
|
||||
is_valid: |value| matches!(value, Value::String(_)),
|
||||
visible: None,
|
||||
specified_by_url: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,12 @@ mod test_mod {
|
|||
|
||||
#[tokio::test]
|
||||
pub async fn test_scalar_macro() {
|
||||
scalar!(test_mod::MyValue, "MV", "DESC");
|
||||
scalar!(
|
||||
test_mod::MyValue,
|
||||
"MV",
|
||||
"DESC",
|
||||
"https://tools.ietf.org/html/rfc4122"
|
||||
);
|
||||
|
||||
struct Query;
|
||||
|
||||
|
@ -26,7 +31,7 @@ pub async fn test_scalar_macro() {
|
|||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
assert_eq!(
|
||||
schema
|
||||
.execute(r#"{ __type(name:"MV") { name description } }"#)
|
||||
.execute(r#"{ __type(name:"MV") { name description specifiedByURL } }"#)
|
||||
.await
|
||||
.into_result()
|
||||
.unwrap()
|
||||
|
@ -35,6 +40,7 @@ pub async fn test_scalar_macro() {
|
|||
"__type": {
|
||||
"name": "MV",
|
||||
"description": "DESC",
|
||||
"specifiedByURL": "https://tools.ietf.org/html/rfc4122",
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue
Block a user