From 612a3af00154d9fa36185788c98e00f4c73fdfa3 Mon Sep 17 00:00:00 2001 From: Magnus Hallin Date: Wed, 19 Oct 2016 21:43:11 +0200 Subject: [PATCH] Update syntax of interface instance resolvers --- src/executor_tests/introspection.rs | 6 +- src/macros/interface.rs | 208 +++++++--------------------- src/macros/object.rs | 6 +- src/macros/tests/field.rs | 6 +- src/macros/tests/interface.rs | 18 +-- src/macros/tests/object.rs | 6 +- src/macros/union.rs | 8 +- src/tests/schema.rs | 8 +- 8 files changed, 81 insertions(+), 185 deletions(-) diff --git a/src/executor_tests/introspection.rs b/src/executor_tests/introspection.rs index 1d0ad324..2fff71a0 100644 --- a/src/executor_tests/introspection.rs +++ b/src/executor_tests/introspection.rs @@ -36,9 +36,9 @@ graphql_interface!(Interface: () as "SampleInterface" |&self| { Sample::One } - instance_resolvers: |&_| [ - Some(Root {}), - ] + instance_resolvers: |&_| { + Root => Some(Root {}), + } }); graphql_object!(Root: () as "Root" |&self| { diff --git a/src/macros/interface.rs b/src/macros/interface.rs index 1519e66d..13a92fd1 100644 --- a/src/macros/interface.rs +++ b/src/macros/interface.rs @@ -22,10 +22,10 @@ with an array of expressions, each resolving into an `Option` of the possible instances: ```rust,ignore -instance_resolvers: |&context| [ - context.get_human(self.id()), // returns Option - context.get_droid(self.id()), // returns Option -], +instance_resolvers: |&context| { + Human => context.get_human(self.id()), // returns Option + Droid => context.get_droid(self.id()), // returns Option +}, ``` Each item in the array will be executed in order when the concrete type is @@ -70,10 +70,10 @@ graphql_object!(Droid: Database as "Droid" |&self| { graphql_interface!(<'a> &'a Character: Database as "Character" |&self| { field id() -> &str { self.id() } - instance_resolvers: |&context| [ - context.humans.get(self.id()), - context.droids.get(self.id()), - ] + instance_resolvers: |&context| { + Human => context.humans.get(self.id()), + Droid => context.droids.get(self.id()), + } }); # fn main() { } @@ -89,8 +89,8 @@ macro_rules! graphql_interface { // field deprecated (...) -> as { ... } ( - @gather_meta, - $reg:expr, $acc:expr, $descr:expr, + @ gather_meta, + ($reg:expr, $acc:expr, $descr:expr), field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )* ) => { $acc.push(__graphql__args!( @@ -102,13 +102,13 @@ macro_rules! graphql_interface { .deprecated($reason), $args)); - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*); + graphql_interface!(@ gather_meta, ($reg, $acc, $descr), $( $rest )*); }; // field deprecated (...) -> { ... } ( - @gather_meta, - $reg:expr, $acc:expr, $descr:expr, + @ gather_meta, + ($reg:expr, $acc:expr, $descr:expr), field deprecated $reason:tt $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* ) => { $acc.push(__graphql__args!( @@ -119,13 +119,13 @@ macro_rules! graphql_interface { .deprecated($reason), $args)); - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*); + graphql_interface!(@ gather_meta, ($reg, $acc, $descr), $( $rest )*); }; // field (...) -> as { ... } ( @gather_meta, - $reg:expr, $acc:expr, $descr:expr, + ($reg:expr, $acc:expr, $descr:expr), field $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )* ) => { $acc.push(__graphql__args!( @@ -136,13 +136,13 @@ macro_rules! graphql_interface { .description($desc), $args)); - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*); + graphql_interface!(@ gather_meta, ($reg, $acc, $descr), $( $rest )*); }; // field (...) -> { ... } ( - @gather_meta, - $reg:expr, $acc:expr, $descr:expr, + @ gather_meta, + ($reg:expr, $acc:expr, $descr:expr), field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* ) => { $acc.push(__graphql__args!( @@ -152,176 +152,60 @@ macro_rules! graphql_interface { &$crate::to_snake_case(stringify!($name))), $args)); - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*); + graphql_interface!(@ gather_meta, ($reg, $acc, $descr), $( $rest )*); }; // description: ( - @gather_meta, - $reg:expr, $acc:expr, $descr:expr, + @ gather_meta, + ($reg:expr, $acc:expr, $descr:expr), description : $value:tt $( $rest:tt )* ) => { $descr = Some(graphql_interface!(@as_expr, $value)); - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*) + graphql_interface!(@gather_meta, ($reg, $acc, $descr), $( $rest )*) }; // instance_resolvers: | | [...] ( - @gather_meta, - $reg:expr, $acc:expr, $descr:expr, - instance_resolvers: | $ctxtvar:pat | $resolvers:tt $( $rest:tt )* - ) => { - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*) - }; - - ( @gather_meta, $reg:expr, $acc:expr, $descr:expr, , $( $rest:tt )* ) => { - graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*) - }; - - ( @gather_meta, $reg:expr, $acc:expr, $descr:expr, ) => { - }; - - // field deprecated (...) -> as { ... } - ( - @resolve_into_type, - $buildargs:tt, - field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )* - ) => { - graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*) - }; - - // field deprecated (...) -> { ... } - ( - @resolve_into_type, - $buildargs:tt, - field deprecated $reason:tt $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* - ) => { - graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*) - }; - - // field (...) -> as { ... } - ( - @resolve_into_type, - $buildargs:tt, - field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )* - ) => { - graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*) - }; - - // field (...) -> { ... } - ( - @resolve_into_type, - $buildargs:tt, - field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* - ) => { - graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*) - }; - - // description: - ( - @resolve_into_type, - $buildargs:tt, description : $value:tt $( $rest:tt )* - ) => { - graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*) - }; - - // field deprecated (...) -> as { ... } - ( - @concrete_type_name, - $buildargs:tt, - field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )* - ) => { - graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*) - }; - - // field deprecated (...) -> { ... } - ( - @concrete_type_name, - $buildargs:tt, - field deprecated $reason:tt $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* - ) => { - graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*) - }; - - // field (...) -> as { ... } - ( - @concrete_type_name, - $buildargs:tt, - field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )* - ) => { - graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*) - }; - - // field (...) -> { ... } - ( - @concrete_type_name, - $buildargs:tt, - field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )* - ) => { - graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*) - }; - - // description: - ( - @concrete_type_name, - $buildargs:tt, description : $value:tt $( $rest:tt )* - ) => { - graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*) - }; - - // instance_resolvers: | | [...] - ( - @concrete_type_name, + @ concrete_type_name, ($outname:tt, $ctxtarg:ident, $ctxttype:ty), - instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr ),* $(,)* ] $( $rest:tt )* + instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )* ) => { let $ctxtvar = &$ctxtarg; - fn inner_type_of(_: T) -> String where T: $crate::GraphQLType<$ctxttype> { - T::name().unwrap().to_owned() - } - $( - if let Some(ref v) = $resolver { - return inner_type_of(v); + if let Some(_) = $resolver { + return (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned(); } )* - panic!("Concrete type not handled by instance resolvers on {}", $outname); - }; - - ( @concrete_type_name, $buildargs:tt, ) => { - () + panic!("Concrete type not handled by instance resolvers on {}", $outname); }; // instance_resolvers: | | ( - @resolve_into_type, + @ resolve_into_type, ($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty), - instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr ),* $(,)* ] $( $rest:tt )* + instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )* ) => { let $ctxtvar = &$execarg.context(); - fn inner_type_of(_: T) -> String where T: $crate::GraphQLType<$ctxttype> { - T::name().unwrap().to_owned() - } - $( - if let Some(ref v) = $resolver { - if inner_type_of(v) == $typenamearg { - return $execarg.resolve(v); - } + if $typenamearg == (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned() { + return $execarg.resolve(&$resolver); } )* - return Ok($crate::Value::null()); + panic!("Concrete type not handled by instance resolvers on {}", $outname); }; - ( @resolve_into_type, $buildargs:tt, ) => { - () + ( @ $mfn:ident, $args:tt, $first:tt $($rest:tt)* ) => { + graphql_interface!(@ $mfn, $args, $($rest)*); }; + ( @ $mfn:ident, $buildargs:tt, ) => {}; + ( ( $($lifetime:tt),* ) $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | { $( $items:tt )* @@ -337,7 +221,7 @@ macro_rules! graphql_interface { fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType { let mut fields = Vec::new(); let mut description = None; - graphql_interface!(@gather_meta, registry, fields, description, $($items)*); + graphql_interface!(@ gather_meta, (registry, fields, description), $($items)*); let mut mt = registry.build_interface_type::<$name>()(&fields); if let Some(description) = description { @@ -350,19 +234,29 @@ macro_rules! graphql_interface { #[allow(unused_variables)] #[allow(unused_mut)] fn resolve_field(&$mainself, field: &str, args: &$crate::Arguments, mut executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult { - __graphql__build_field_matches!(($outname, $mainself, field, args, executor), (), $($items)*); + __graphql__build_field_matches!( + ($outname, $mainself, field, args, executor), + (), + $($items)*); } fn concrete_type_name(&$mainself, context: &$ctxt) -> String { graphql_interface!( - @concrete_type_name, + @ concrete_type_name, ($outname, context, $ctxt), $($items)*); } - fn resolve_into_type(&$mainself, type_name: &str, _: Option>, executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult { + fn resolve_into_type( + &$mainself, + type_name: &str, + _: Option>, + executor: &mut $crate::Executor<$ctxt>, + ) + -> $crate::ExecutionResult + { graphql_interface!( - @resolve_into_type, + @ resolve_into_type, ($outname, type_name, executor, $ctxt), $($items)*); } diff --git a/src/macros/object.rs b/src/macros/object.rs index 8d6df382..22079547 100644 --- a/src/macros/object.rs +++ b/src/macros/object.rs @@ -100,9 +100,9 @@ struct Implementor { id: String } graphql_interface!(<'a> &'a Interface: () as "Interface" |&self| { field id() -> &str { self.id() } - instance_resolvers: |&context| [ - self.as_implementor(), - ] + instance_resolvers: |&context| { + Implementor => self.as_implementor(), + } }); graphql_object!(Implementor: () as "Implementor" |&self| { diff --git a/src/macros/tests/field.rs b/src/macros/tests/field.rs index c004bccc..8e7dd607 100644 --- a/src/macros/tests/field.rs +++ b/src/macros/tests/field.rs @@ -42,9 +42,9 @@ graphql_interface!(Interface: () as "Interface" |&self| { field deprecated "Deprecation reason" deprecated_descr() -> i64 as "Field description" { 0 } - instance_resolvers: |&_| [ - Some(Root {}), - ] + instance_resolvers: |&_| { + Root => Some(Root {}), + } }); fn run_field_info_query(type_name: &str, field_name: &str, f: F) diff --git a/src/macros/tests/interface.rs b/src/macros/tests/interface.rs index f1fe5d92..db7fa027 100644 --- a/src/macros/tests/interface.rs +++ b/src/macros/tests/interface.rs @@ -45,18 +45,18 @@ graphql_object!(Concrete: () |&self| { graphql_interface!(DefaultName: () |&self| { field simple() -> i64 { 0 } - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } }); graphql_interface!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| { field simple() -> i64 { 0 } - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } }); graphql_interface!( WithGenerics: () as "WithGenerics" |&self| { field simple() -> i64 { 0 } - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } }); @@ -65,7 +65,7 @@ graphql_interface!(DescriptionFirst: () as "DescriptionFirst" |&self| { field simple() -> i64 { 0 } - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } }); graphql_interface!(FieldsFirst: () as "FieldsFirst" |&self| { @@ -73,11 +73,11 @@ graphql_interface!(FieldsFirst: () as "FieldsFirst" |&self| { description: "A description" - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } }); graphql_interface!(InterfacesFirst: () as "InterfacesFirst" |&self| { - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } field simple() -> i64 { 0 } @@ -85,7 +85,7 @@ graphql_interface!(InterfacesFirst: () as "InterfacesFirst" |&self| { }); graphql_interface!(CommasWithTrailing: () as "CommasWithTrailing" |&self| { - instance_resolvers: |_| [ Some(Concrete) ], + instance_resolvers: |_| { Concrete => Some(Concrete) }, field simple() -> i64 { 0 }, @@ -94,7 +94,7 @@ graphql_interface!(CommasWithTrailing: () as "CommasWithTrailing" |&self| { graphql_interface!(CommasOnMeta: () as "CommasOnMeta" |&self| { - instance_resolvers: |_| [ Some(Concrete) ] + instance_resolvers: |_| { Concrete => Some(Concrete) } description: "A description", field simple() -> i64 { 0 } @@ -102,7 +102,7 @@ graphql_interface!(CommasOnMeta: () as "CommasOnMeta" |&self| { graphql_interface!(ResolversWithTrailingComma: () as "ResolversWithTrailingComma" |&self| { - instance_resolvers: |_| [ Some(Concrete), ] + instance_resolvers: |_| { Concrete => Some(Concrete), } description: "A description", field simple() -> i64 { 0 } diff --git a/src/macros/tests/object.rs b/src/macros/tests/object.rs index cfcecccb..41c59308 100644 --- a/src/macros/tests/object.rs +++ b/src/macros/tests/object.rs @@ -52,9 +52,9 @@ graphql_object!( WithGenerics: () as "WithGenerics" |&self| { graphql_interface!(Interface: () as "Interface" |&self| { field simple() -> i64 { 0 } - instance_resolvers: |_| [ - Some(DescriptionFirst {}), - ] + instance_resolvers: |_| { + DescriptionFirst => Some(DescriptionFirst {}), + } }); graphql_object!(DescriptionFirst: () as "DescriptionFirst" |&self| { diff --git a/src/macros/union.rs b/src/macros/union.rs index 362f0e25..38737501 100644 --- a/src/macros/union.rs +++ b/src/macros/union.rs @@ -37,7 +37,7 @@ macro_rules! graphql_union { ( @ concrete_type_name, ($outname:tt, $ctxtarg:ident, $ctxttype:ty), - instance_resolvers: | $ctxtvar:pat | { $( $srctype:path => $resolver:expr ),* $(,)* } $( $rest:tt )* + instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )* ) => { let $ctxtvar = &$ctxtarg; @@ -55,7 +55,7 @@ macro_rules! graphql_union { ( @ resolve_into_type, ($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty), - instance_resolvers: | $ctxtvar:pat | { $( $srctype:path => $resolver:expr ),* $(,)* } $( $rest:tt )* + instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )* ) => { let $ctxtvar = &$execarg.context(); @@ -118,7 +118,9 @@ macro_rules! graphql_union { type_name: &str, _: Option>, executor: &mut $crate::Executor<$ctxt>, - ) -> $crate::ExecutionResult { + ) + -> $crate::ExecutionResult + { graphql_union!( @ resolve_into_type, ($outname, type_name, executor, $ctxt), diff --git a/src/tests/schema.rs b/src/tests/schema.rs index cde33b12..5758b21f 100644 --- a/src/tests/schema.rs +++ b/src/tests/schema.rs @@ -26,10 +26,10 @@ graphql_interface!(<'a> &'a Character: Database as "Character" |&self| { self.appears_in() } - instance_resolvers: |&context| [ - context.get_human(&self.id()), - context.get_droid(&self.id()), - ] + instance_resolvers: |&context| { + &'a Human => context.get_human(&self.id()), + &'a Droid => context.get_droid(&self.id()), + } }); graphql_object!(<'a> &'a Human: Database as "Human" |&self| {