From f4887badeb49fa2df815a3099efadc39c51cf2db Mon Sep 17 00:00:00 2001 From: Magnus Hallin Date: Thu, 20 Oct 2016 20:43:47 +0200 Subject: [PATCH] Add documentation for the union helper macro --- src/macros/interface.rs | 21 ++++++++++++--------- src/macros/union.rs | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/macros/interface.rs b/src/macros/interface.rs index 3db0314e..be120a6a 100644 --- a/src/macros/interface.rs +++ b/src/macros/interface.rs @@ -16,20 +16,23 @@ See the documentation for [`graphql_object!`][1] on the general item and type syntax. `graphql_interface!` requires an additional `instance_resolvers` item, and does _not_ support the `interfaces` item. -`instance_resolvers` is a list/lambda hybrid used to resolve the concrete +`instance_resolvers` is a match like structure used to resolve the concrete instance type of the interface. It starts with a context argument and continues -with an array of expressions, each resolving into an `Option` of the possible -instances: +with a number of match arms; on the left side is the indicated type, and on the +right an expression that resolve into `Option` of the type indicated: ```rust,ignore instance_resolvers: |&context| { - Human => context.get_human(self.id()), // returns Option - Droid => context.get_droid(self.id()), // returns Option + &Human => context.get_human(self.id()), // returns Option<&Human> + &Droid => context.get_droid(self.id()), // returns Option<&Droid> }, ``` -Each item in the array will be executed in order when the concrete type is -required. +This is used for both the `__typename` field and when resolving a specialized +fragment, e.g. `...on Human`. For `__typename`, the resolvers will be executed +in order - the first one returning `Some` will be the determined type name. When +resolving fragment type conditions, only the corresponding match arm will be +executed. ## Example @@ -71,8 +74,8 @@ graphql_interface!(<'a> &'a Character: Database as "Character" |&self| { field id() -> &str { self.id() } instance_resolvers: |&context| { - Human => context.humans.get(self.id()), - Droid => context.droids.get(self.id()), + &Human => context.humans.get(self.id()), + &Droid => context.droids.get(self.id()), } }); diff --git a/src/macros/union.rs b/src/macros/union.rs index 0243bcd9..aeaed936 100644 --- a/src/macros/union.rs +++ b/src/macros/union.rs @@ -1,3 +1,22 @@ +/** +Expose GraphQL unions + +Like interfaces, mapping unions can be tricky in idiomatic Rust. Because of +their similarity, the helper macros are similar, too: you provide a set of +expressions that resolve the union into the actual concrete type. + +## Syntax + +See the documentation for [`graphql_object!`][1] on the general item and type +syntax. `graphql_union!` supports only `description` and `interface_resolvers` +items, no fields or interfaces can be declared. + +See the documentation for [`graphql_interface!`][2] on the syntax for interface +resolvers. + +[1]: macro.graphql_object!.html +[2]: macro.graphql_interface!.html +*/ #[macro_export] macro_rules! graphql_union { ( @as_item, $i:item) => { $i };