Allow top-level #[graphql]
attribute in attribute macros (#1232)
This commit is contained in:
parent
c0e1b3eae3
commit
9420f3c19e
12 changed files with 140 additions and 76 deletions
|
@ -11,21 +11,51 @@ pub(crate) mod rename;
|
|||
pub(crate) mod scalar;
|
||||
mod span_container;
|
||||
|
||||
use std::slice;
|
||||
|
||||
pub(crate) use self::{description::Description, span_container::SpanContainer};
|
||||
|
||||
/// Checks whether the specified [`syn::Path`] equals to one-segment string
|
||||
/// `value`.
|
||||
pub(crate) fn path_eq_single(path: &syn::Path, value: &str) -> bool {
|
||||
path.segments.len() == 1 && path.segments[0].ident == value
|
||||
/// Checks whether the specified [`syn::Path`] equals to one of specified one-segment
|
||||
/// [`AttrNames::values`].
|
||||
pub(crate) fn path_eq_single(path: &syn::Path, names: impl AttrNames) -> bool {
|
||||
path.segments.len() == 1
|
||||
&& names
|
||||
.values()
|
||||
.iter()
|
||||
.any(|name| path.segments[0].ident == name)
|
||||
}
|
||||
|
||||
/// Filters the provided [`syn::Attribute`] to contain only ones with the
|
||||
/// specified `name`.
|
||||
pub(crate) fn filter_attrs<'a>(
|
||||
name: &'a str,
|
||||
names: impl AttrNames + 'a,
|
||||
attrs: &'a [syn::Attribute],
|
||||
) -> impl Iterator<Item = &'a syn::Attribute> + 'a {
|
||||
attrs
|
||||
.iter()
|
||||
.filter(move |attr| path_eq_single(attr.path(), name))
|
||||
.filter(move |attr| path_eq_single(attr.path(), names))
|
||||
}
|
||||
|
||||
/// Input-type polymorphism helper for checking names of multiple attribute names.
|
||||
pub(crate) trait AttrNames: Copy {
|
||||
/// Returns values to be checked.
|
||||
fn values(&self) -> &[&str];
|
||||
}
|
||||
|
||||
impl AttrNames for &str {
|
||||
fn values(&self) -> &[&str] {
|
||||
slice::from_ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl AttrNames for &[&str] {
|
||||
fn values(&self) -> &[&str] {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> AttrNames for [&str; N] {
|
||||
fn values(&self) -> &[&str] {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use proc_macro2::{Span, TokenStream};
|
||||
use syn::parse_quote;
|
||||
|
||||
use crate::common::path_eq_single;
|
||||
use crate::common::{path_eq_single, AttrNames};
|
||||
|
||||
/// Prepends the given `attrs` collection with a new [`syn::Attribute`] generated from the given
|
||||
/// `attr_path` and `attr_args`.
|
||||
|
@ -25,10 +25,10 @@ pub(crate) fn unite(
|
|||
///
|
||||
/// This function is generally used for removing duplicate attributes during `proc_macro_attribute`
|
||||
/// expansion, so avoid unnecessary expansion duplication.
|
||||
pub(crate) fn strip(attr_path: &str, attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> {
|
||||
pub(crate) fn strip(names: impl AttrNames, attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> {
|
||||
attrs
|
||||
.into_iter()
|
||||
.filter(|attr| !path_eq_single(attr.path(), attr_path))
|
||||
.filter(|attr| !path_eq_single(attr.path(), names))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ const ERR: diagnostic::Scope = diagnostic::Scope::InterfaceAttr;
|
|||
pub fn expand(attr_args: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
|
||||
if let Ok(mut ast) = syn::parse2::<syn::ItemTrait>(body.clone()) {
|
||||
let trait_attrs = parse::attr::unite(("graphql_interface", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_interface", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_interface", "graphql"], ast.attrs);
|
||||
return expand_on_trait(trait_attrs, ast);
|
||||
}
|
||||
if let Ok(mut ast) = syn::parse2::<syn::DeriveInput>(body) {
|
||||
let trait_attrs = parse::attr::unite(("graphql_interface", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_interface", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_interface", "graphql"], ast.attrs);
|
||||
return expand_on_derive_input(trait_attrs, ast);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ fn expand_on_trait(
|
|||
attrs: Vec<syn::Attribute>,
|
||||
mut ast: syn::ItemTrait,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let attr = Attr::from_attrs("graphql_interface", &attrs)?;
|
||||
let attr = Attr::from_attrs(["graphql_interface", "graphql"], &attrs)?;
|
||||
|
||||
let trait_ident = &ast.ident;
|
||||
let trait_span = ast.span();
|
||||
|
@ -220,7 +220,7 @@ fn expand_on_derive_input(
|
|||
attrs: Vec<syn::Attribute>,
|
||||
mut ast: syn::DeriveInput,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let attr = Attr::from_attrs("graphql_interface", &attrs)?;
|
||||
let attr = Attr::from_attrs(["graphql_interface", "graphql"], &attrs)?;
|
||||
|
||||
let struct_ident = &ast.ident;
|
||||
let struct_span = ast.span();
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::common::{
|
|||
attr::{err, OptionExt as _},
|
||||
GenericsExt as _, ParseBufferExt as _,
|
||||
},
|
||||
rename, scalar, Description, SpanContainer,
|
||||
rename, scalar, AttrNames, Description, SpanContainer,
|
||||
};
|
||||
|
||||
/// Returns [`syn::Ident`]s for a generic enum deriving [`Clone`] and [`Copy`]
|
||||
|
@ -254,10 +254,10 @@ impl Attr {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parses [`TraitAttr`] from the given multiple `name`d [`syn::Attribute`]s
|
||||
/// placed on a trait definition.
|
||||
fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(name, attrs)
|
||||
/// Parses a [`TraitAttr`] from the provided multiple [`syn::Attribute`]s with
|
||||
/// the specified `names`, placed on a trait or struct definition.
|
||||
fn from_attrs(names: impl AttrNames, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(names, attrs)
|
||||
.map(|attr| attr.parse_args())
|
||||
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
|
||||
|
||||
|
|
|
@ -22,8 +22,11 @@ pub fn expand(attr_args: TokenStream, body: TokenStream) -> syn::Result<TokenStr
|
|||
if let Ok(mut ast) = syn::parse2::<syn::ItemImpl>(body) {
|
||||
if ast.trait_.is_none() {
|
||||
let impl_attrs = parse::attr::unite(("graphql_object", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_object", ast.attrs);
|
||||
return expand_on_impl::<Query>(Attr::from_attrs("graphql_object", &impl_attrs)?, ast);
|
||||
ast.attrs = parse::attr::strip(["graphql_object", "graphql"], ast.attrs);
|
||||
return expand_on_impl::<Query>(
|
||||
Attr::from_attrs(["graphql_object", "graphql"], &impl_attrs)?,
|
||||
ast,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::common::{
|
|||
attr::{err, OptionExt as _},
|
||||
GenericsExt as _, ParseBufferExt as _, TypeExt,
|
||||
},
|
||||
rename, scalar, Description, SpanContainer,
|
||||
rename, scalar, AttrNames, Description, SpanContainer,
|
||||
};
|
||||
|
||||
/// Available arguments behind `#[graphql]` (or `#[graphql_object]`) attribute
|
||||
|
@ -181,10 +181,10 @@ impl Attr {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parses [`Attr`] from the given multiple `name`d [`syn::Attribute`]s
|
||||
/// placed on a struct or impl block definition.
|
||||
pub(crate) fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(name, attrs)
|
||||
/// Parses an [`Attr`] from the provided multiple [`syn::Attribute`]s with
|
||||
/// the specified `names`, placed on a struct or impl block definition.
|
||||
pub(crate) fn from_attrs(names: impl AttrNames, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(names, attrs)
|
||||
.map(|attr| attr.parse_args())
|
||||
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@ const ERR: diagnostic::Scope = diagnostic::Scope::ScalarAttr;
|
|||
pub(crate) fn expand(attr_args: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
|
||||
if let Ok(mut ast) = syn::parse2::<syn::ItemType>(body.clone()) {
|
||||
let attrs = parse::attr::unite(("graphql_scalar", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_scalar", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_scalar", "graphql"], ast.attrs);
|
||||
return expand_on_type_alias(attrs, ast);
|
||||
} else if let Ok(mut ast) = syn::parse2::<syn::DeriveInput>(body) {
|
||||
let attrs = parse::attr::unite(("graphql_scalar", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_scalar", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_scalar", "graphql"], ast.attrs);
|
||||
return expand_on_derive_input(attrs, ast);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ fn expand_on_type_alias(
|
|||
attrs: Vec<syn::Attribute>,
|
||||
ast: syn::ItemType,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let attr = Attr::from_attrs("graphql_scalar", &attrs)?;
|
||||
let attr = Attr::from_attrs(["graphql_scalar", "graphql"], &attrs)?;
|
||||
if attr.transparent {
|
||||
return Err(ERR.custom_error(
|
||||
ast.span(),
|
||||
|
@ -73,7 +73,7 @@ fn expand_on_derive_input(
|
|||
attrs: Vec<syn::Attribute>,
|
||||
ast: syn::DeriveInput,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let attr = Attr::from_attrs("graphql_scalar", &attrs)?;
|
||||
let attr = Attr::from_attrs(["graphql_scalar", "graphql"], &attrs)?;
|
||||
let methods = parse_derived_methods(&ast, &attr)?;
|
||||
let scalar = scalar::Type::parse(attr.scalar.as_deref(), &ast.generics);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::common::{
|
|||
attr::{err, OptionExt as _},
|
||||
ParseBufferExt as _,
|
||||
},
|
||||
scalar, Description, SpanContainer,
|
||||
scalar, AttrNames, Description, SpanContainer,
|
||||
};
|
||||
|
||||
pub mod attr;
|
||||
|
@ -240,10 +240,10 @@ impl Attr {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parses [`Attr`] from the given multiple `name`d [`syn::Attribute`]s
|
||||
/// placed on a trait definition.
|
||||
fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(name, attrs)
|
||||
/// Parses an [`Attr`] from the provided multiple [`syn::Attribute`]s with
|
||||
/// the specified `names`, placed on a type definition.
|
||||
fn from_attrs(names: impl AttrNames, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut attr = filter_attrs(names, attrs)
|
||||
.map(|attr| attr.parse_args())
|
||||
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@ pub fn expand(attr_args: TokenStream, body: TokenStream) -> syn::Result<TokenStr
|
|||
if let Ok(mut ast) = syn::parse2::<syn::ItemImpl>(body) {
|
||||
if ast.trait_.is_none() {
|
||||
let impl_attrs = parse::attr::unite(("graphql_subscription", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_subscription", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_subscription", "graphql"], ast.attrs);
|
||||
return expand_on_impl::<Subscription>(
|
||||
Attr::from_attrs("graphql_subscription", &impl_attrs)?,
|
||||
Attr::from_attrs(["graphql_subscription", "graphql"], &impl_attrs)?,
|
||||
ast,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ const ERR: diagnostic::Scope = diagnostic::Scope::UnionAttr;
|
|||
pub fn expand(attr_args: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
|
||||
if let Ok(mut ast) = syn::parse2::<syn::ItemTrait>(body) {
|
||||
let trait_attrs = parse::attr::unite(("graphql_union", &attr_args), &ast.attrs);
|
||||
ast.attrs = parse::attr::strip("graphql_union", ast.attrs);
|
||||
ast.attrs = parse::attr::strip(["graphql_union", "graphql"], ast.attrs);
|
||||
return expand_on_trait(trait_attrs, ast);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ fn expand_on_trait(
|
|||
attrs: Vec<syn::Attribute>,
|
||||
mut ast: syn::ItemTrait,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let attr = Attr::from_attrs("graphql_union", &attrs)?;
|
||||
let attr = Attr::from_attrs(["graphql_union", "graphql"], &attrs)?;
|
||||
|
||||
let trait_span = ast.span();
|
||||
let trait_ident = &ast.ident;
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::common::{
|
|||
attr::{err, OptionExt as _},
|
||||
ParseBufferExt as _,
|
||||
},
|
||||
scalar, Description, SpanContainer,
|
||||
scalar, AttrNames, Description, SpanContainer,
|
||||
};
|
||||
|
||||
/// Helper alias for the type of [`Attr::external_resolvers`] field.
|
||||
|
@ -167,10 +167,10 @@ impl Attr {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parses [`Attr`] from the given multiple `name`d [`syn::Attribute`]s
|
||||
/// placed on a type definition.
|
||||
fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut meta = filter_attrs(name, attrs)
|
||||
/// Parses an [`Attr`] from the provided multiple [`syn::Attribute`]s with
|
||||
/// the specified `names`, placed on a trait or type definition.
|
||||
fn from_attrs(names: impl AttrNames, attrs: &[syn::Attribute]) -> syn::Result<Self> {
|
||||
let mut meta = filter_attrs(names, attrs)
|
||||
.map(|attr| attr.parse_args())
|
||||
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
|
||||
|
||||
|
|
|
@ -674,7 +674,8 @@ pub fn derive_scalar(input: TokenStream) -> TokenStream {
|
|||
/// # use juniper::graphql_scalar;
|
||||
/// #
|
||||
/// /// Doc comments are used for the GraphQL type description.
|
||||
/// #[graphql_scalar(
|
||||
/// #[graphql_scalar]
|
||||
/// #[graphql(
|
||||
/// // Custom GraphQL name.
|
||||
/// name = "MyUserId",
|
||||
/// // Description can also specified in the attribute.
|
||||
|
@ -721,7 +722,8 @@ pub fn derive_scalar(input: TokenStream) -> TokenStream {
|
|||
/// # use juniper::DefaultScalarValue as CustomScalarValue;
|
||||
/// use juniper::{graphql_scalar, InputValue, ScalarValue, Value};
|
||||
///
|
||||
/// #[graphql_scalar(
|
||||
/// #[graphql_scalar]
|
||||
/// #[graphql(
|
||||
/// with = date_scalar,
|
||||
/// parse_token(String),
|
||||
/// scalar = CustomScalarValue,
|
||||
|
@ -897,7 +899,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
///
|
||||
/// // NOTICE: By default a `CharacterValue` enum is generated by macro to represent values of this
|
||||
/// // GraphQL interface.
|
||||
/// #[graphql_interface(for = Human)] // enumerating all implementers is mandatory
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = Human)] // enumerating all implementers is mandatory
|
||||
/// struct Character {
|
||||
/// id: String,
|
||||
/// }
|
||||
|
@ -917,7 +920,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
///
|
||||
/// // NOTICE: By default a `CharacterValue` enum is generated by macro to represent values of this
|
||||
/// // GraphQL interface.
|
||||
/// #[graphql_interface(for = Human)] // enumerating all implementers is mandatory
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = Human)] // enumerating all implementers is mandatory
|
||||
/// trait Character {
|
||||
/// fn id(&self) -> &str;
|
||||
/// }
|
||||
|
@ -953,7 +957,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// ```rust
|
||||
/// # use juniper::graphql_interface;
|
||||
/// #
|
||||
/// #[graphql_interface(name = "Character", desc = "Possible episode characters.")]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(name = "Character", desc = "Possible episode characters.")]
|
||||
/// trait Chrctr {
|
||||
/// #[graphql(name = "id", desc = "ID of the character.")]
|
||||
/// #[graphql(deprecated = "Don't use it")]
|
||||
|
@ -988,12 +993,14 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// # extern crate juniper;
|
||||
/// use juniper::{graphql_interface, graphql_object, ID};
|
||||
///
|
||||
/// #[graphql_interface(for = [HumanValue, Luke])]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = [HumanValue, Luke])]
|
||||
/// struct Node {
|
||||
/// id: ID,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_interface(impl = NodeValue, for = Luke)]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(impl = NodeValue, for = Luke)]
|
||||
/// struct Human {
|
||||
/// id: ID,
|
||||
/// home_planet: String,
|
||||
|
@ -1003,7 +1010,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// id: ID,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_object(impl = [HumanValue, NodeValue])]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(impl = [HumanValue, NodeValue])]
|
||||
/// impl Luke {
|
||||
/// fn id(&self) -> &ID {
|
||||
/// &self.id
|
||||
|
@ -1043,23 +1051,27 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// # extern crate juniper;
|
||||
/// use juniper::{graphql_interface, graphql_object, ID};
|
||||
///
|
||||
/// #[graphql_interface(for = [HumanValue, Luke])]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = [HumanValue, Luke])]
|
||||
/// struct Node {
|
||||
/// id: ID,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_interface(for = HumanConnectionValue)]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = HumanConnectionValue)]
|
||||
/// struct Connection {
|
||||
/// nodes: Vec<NodeValue>,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_interface(impl = NodeValue, for = Luke)]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(impl = NodeValue, for = Luke)]
|
||||
/// struct Human {
|
||||
/// id: ID,
|
||||
/// home_planet: String,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_interface(impl = ConnectionValue)]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(impl = ConnectionValue)]
|
||||
/// struct HumanConnection {
|
||||
/// nodes: Vec<HumanValue>,
|
||||
/// // ^^^^^^^^^^ notice not `NodeValue`
|
||||
|
@ -1072,7 +1084,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// id: ID,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_object(impl = [HumanValue, NodeValue])]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(impl = [HumanValue, NodeValue])]
|
||||
/// impl Luke {
|
||||
/// fn id(&self) -> &ID {
|
||||
/// &self.id
|
||||
|
@ -1109,7 +1122,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// ```rust
|
||||
/// # use juniper::{graphql_interface, graphql_object};
|
||||
/// #
|
||||
/// #[graphql_interface(for = Human, rename_all = "none")] // disables renaming
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = Human, rename_all = "none")] // disables renaming
|
||||
/// trait Character {
|
||||
/// // NOTICE: In the generated GraphQL schema this field and its argument
|
||||
/// // will be `detailed_info` and `info_kind`.
|
||||
|
@ -1121,7 +1135,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// home_planet: String,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_object(impl = CharacterValue, rename_all = "none")]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(impl = CharacterValue, rename_all = "none")]
|
||||
/// impl Human {
|
||||
/// fn id(&self) -> &str {
|
||||
/// &self.id
|
||||
|
@ -1179,7 +1194,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// }
|
||||
/// impl juniper::Context for Database {}
|
||||
///
|
||||
/// #[graphql_interface(for = [Human, Droid], Context = Database)]
|
||||
/// #[graphql_interface]
|
||||
/// #[graphql(for = [Human, Droid], Context = Database)]
|
||||
/// trait Character {
|
||||
/// fn id<'db>(&self, ctx: &'db Database) -> Option<&'db str>;
|
||||
/// fn info<'db>(&self, #[graphql(context)] db: &'db Database) -> Option<&'db str>;
|
||||
|
@ -1189,7 +1205,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// id: String,
|
||||
/// home_planet: String,
|
||||
/// }
|
||||
/// #[graphql_object(impl = CharacterValue, Context = Database)]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(impl = CharacterValue, Context = Database)]
|
||||
/// impl Human {
|
||||
/// fn id<'db>(&self, context: &'db Database) -> Option<&'db str> {
|
||||
/// context.humans.get(&self.id).map(|h| h.id.as_str())
|
||||
|
@ -1206,7 +1223,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// id: String,
|
||||
/// primary_function: String,
|
||||
/// }
|
||||
/// #[graphql_object(impl = CharacterValue, Context = Database)]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(impl = CharacterValue, Context = Database)]
|
||||
/// impl Droid {
|
||||
/// fn id<'db>(&self, ctx: &'db Database) -> Option<&'db str> {
|
||||
/// ctx.droids.get(&self.id).map(|h| h.id.as_str())
|
||||
|
@ -1231,8 +1249,9 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// ```rust
|
||||
/// # use juniper::{graphql_interface, graphql_object, Executor, LookAheadMethods as _, ScalarValue};
|
||||
/// #
|
||||
/// #[graphql_interface]
|
||||
/// // NOTICE: Specifying `ScalarValue` as existing type parameter.
|
||||
/// #[graphql_interface(for = Human, scalar = S)]
|
||||
/// #[graphql(for = Human, scalar = S)]
|
||||
/// trait Character<S: ScalarValue> {
|
||||
/// fn id<'a>(&self, executor: &'a Executor<'_, '_, (), S>) -> &'a str;
|
||||
///
|
||||
|
@ -1246,7 +1265,8 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// id: String,
|
||||
/// name: String,
|
||||
/// }
|
||||
/// #[graphql_object(scalar = S: ScalarValue, impl = CharacterValue<S>)]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(scalar = S: ScalarValue, impl = CharacterValue<S>)]
|
||||
/// impl Human {
|
||||
/// async fn id<'a, S>(&self, executor: &'a Executor<'_, '_, (), S>) -> &'a str
|
||||
/// where
|
||||
|
@ -1273,8 +1293,9 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
|||
/// ```rust
|
||||
/// # use juniper::{graphql_interface, DefaultScalarValue, GraphQLObject};
|
||||
/// #
|
||||
/// #[graphql_interface]
|
||||
/// // NOTICE: Removing `Scalar` argument will fail compilation.
|
||||
/// #[graphql_interface(for = Human, scalar = DefaultScalarValue)]
|
||||
/// #[graphql(for = Human, scalar = DefaultScalarValue)]
|
||||
/// trait Character {
|
||||
/// fn id(&self) -> &str;
|
||||
/// }
|
||||
|
@ -1585,7 +1606,8 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
|||
/// #
|
||||
/// struct HumanWithAttrs;
|
||||
///
|
||||
/// #[graphql_object(
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(
|
||||
/// // Rename the type for GraphQL by specifying the name here.
|
||||
/// name = "Human",
|
||||
/// // You may also specify a description here.
|
||||
|
@ -1643,7 +1665,8 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
|||
/// #
|
||||
/// struct Query;
|
||||
///
|
||||
/// #[graphql_object(rename_all = "none")] // disables renaming
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(rename_all = "none")] // disables renaming
|
||||
/// impl Query {
|
||||
/// // NOTICE: In the generated GraphQL schema this field will be available
|
||||
/// // as `api_version`.
|
||||
|
@ -1708,7 +1731,8 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
|||
/// home_planet: String,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_object(context = Database)]
|
||||
/// #[graphql_object]
|
||||
/// #[graphql(context = Database)]
|
||||
/// impl Human {
|
||||
/// fn id<'db>(&self, context: &'db Database) -> Option<&'db str> {
|
||||
/// context.humans.get(&self.id).map(|h| h.id.as_str())
|
||||
|
@ -1736,9 +1760,10 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
|||
/// name: String,
|
||||
/// }
|
||||
///
|
||||
/// #[graphql_object]
|
||||
/// // NOTICE: Specifying `ScalarValue` as custom named type parameter.
|
||||
/// // Its name should be similar to the one used in methods.
|
||||
/// #[graphql_object(scalar = S: ScalarValue)]
|
||||
/// #[graphql(scalar = S: ScalarValue)]
|
||||
/// impl Human {
|
||||
/// async fn id<'a, S: ScalarValue>(
|
||||
/// &self,
|
||||
|
@ -1769,8 +1794,9 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
|||
/// #
|
||||
/// struct Human(String);
|
||||
///
|
||||
/// #[graphql_object]
|
||||
/// // NOTICE: Removing `scalar` argument will fail compilation.
|
||||
/// #[graphql_object(scalar = DefaultScalarValue)]
|
||||
/// #[graphql(scalar = DefaultScalarValue)]
|
||||
/// impl Human {
|
||||
/// fn id(&self) -> &str {
|
||||
/// &self.0
|
||||
|
@ -2232,7 +2258,8 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
|||
/// # primary_function: String,
|
||||
/// # }
|
||||
/// #
|
||||
/// #[graphql_union(name = "Character", desc = "Possible episode characters.")]
|
||||
/// #[graphql_union]
|
||||
/// #[graphql(name = "Character", desc = "Possible episode characters.")]
|
||||
/// trait Chrctr {
|
||||
/// fn as_human(&self) -> Option<&Human> { None }
|
||||
/// fn as_droid(&self) -> Option<&Droid> { None }
|
||||
|
@ -2247,7 +2274,8 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
|||
///
|
||||
/// // NOTICE: `description` argument takes precedence over Rust docs.
|
||||
/// /// Not a GraphQL description anymore.
|
||||
/// #[graphql_union(description = "Possible episode characters.")]
|
||||
/// #[graphql_union]
|
||||
/// #[graphql(description = "Possible episode characters.")]
|
||||
/// trait CharacterWithDescription {
|
||||
/// fn as_human(&self) -> Option<&Human> { None }
|
||||
/// fn as_droid(&self) -> Option<&Droid> { None }
|
||||
|
@ -2293,7 +2321,8 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
|||
/// }
|
||||
/// impl juniper::Context for Database {}
|
||||
///
|
||||
/// #[graphql_union(Context = Database)]
|
||||
/// #[graphql_union]
|
||||
/// #[graphql(context = Database)]
|
||||
/// trait Character {
|
||||
/// fn as_human<'db>(&self, ctx: &'db Database) -> Option<&'db Human> { None }
|
||||
/// fn as_droid<'db>(&self, ctx: &'db Database) -> Option<&'db Droid> { None }
|
||||
|
@ -2336,8 +2365,9 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
|||
/// primary_function: String,
|
||||
/// }
|
||||
///
|
||||
/// // NOTICE: Removing `Scalar` argument will fail compilation.
|
||||
/// #[graphql_union(scalar = DefaultScalarValue)]
|
||||
/// // NOTICE: Removing `scalar` argument will fail compilation.
|
||||
/// #[graphql_union]
|
||||
/// #[graphql(scalar = DefaultScalarValue)]
|
||||
/// trait Character {
|
||||
/// fn as_human(&self) -> Option<&Human> { None }
|
||||
/// fn as_droid(&self) -> Option<&Droid> { None }
|
||||
|
@ -2413,8 +2443,9 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
|||
/// }
|
||||
/// impl juniper::Context for Database {}
|
||||
///
|
||||
/// #[graphql_union(Context = Database)]
|
||||
/// #[graphql_union(
|
||||
/// #[graphql_union]
|
||||
/// #[graphql(context = Database)]
|
||||
/// #[graphql(
|
||||
/// on Human = DynCharacter::get_human,
|
||||
/// on Droid = get_droid,
|
||||
/// )]
|
||||
|
|
Loading…
Reference in a new issue