@@ -16,7 +16,9 @@ datatype appropriate for that platform.
1616# use juniper::{Value, FieldResult};
1717struct UserID(String);
1818
19- graphql_scalar!(UserID as "UserID" {
19+ graphql_scalar!(UserID {
20+ description: "An opaque identifier, represented as a string"
21+
2022 resolve(&self) -> Value {
2123 Value::string(&self.0)
2224 }
@@ -33,77 +35,113 @@ In addition to implementing `GraphQLType` for the type in question,
3335`FromInputValue` and `ToInputValue` is also implemented. This makes the type
3436usable as arguments and default values.
3537
36- `graphql_scalar!` supports generic and lifetime parameters similar to
37- `graphql_object!`.
38-
3938*/
4039#[ macro_export]
4140macro_rules! graphql_scalar {
41+ // Calls $val.$func($arg) if $arg is not None
42+ ( @maybe_apply, None , $func: ident, $val: expr ) => { $val } ;
43+ ( @maybe_apply, $arg: tt, $func: ident, $val: expr ) => { $val. $func( $arg) } ;
44+
45+ // Each of the @parse match arms accumulates data up to a call to @generate
46+ //
47+ // ( $name, $outname, $descr ): the name of the Rust type and the name of the
48+ // GraphQL scalar (as a string), and the description of the scalar (as a
49+ // string or none).
50+ //
51+ // ( $resolve_selfvar, $resolve_body ): the "self" argument and body for the
52+ // resolve() method on GraphQLType and the to() method on ToInputValue.
53+ //
54+ // ( $fiv_arg, $fiv_result, $fiv_body ): the method argument, result type,
55+ // and body for the from() method on FromInputValue.
4256 (
43- @build_scalar_resolver,
44- resolve( & $selfvar: ident) -> Value $body: block $( $rest: tt) *
57+ @generate,
58+ ( $name: ty, $outname: tt, $descr: tt ) ,
59+ (
60+ ( $resolve_selfvar: ident, $resolve_body: block ) ,
61+ ( $fiv_arg: ident, $fiv_result: ty, $fiv_body: block )
62+ )
4563 ) => {
46- fn resolve( & $selfvar, _: Option <Vec <$crate:: Selection >>, _: & mut $crate:: Executor <CtxT >) -> $crate:: Value {
47- $body
64+ impl <CtxT > $crate:: GraphQLType <CtxT > for $name {
65+ fn name( ) -> Option <& ' static str > {
66+ Some ( $outname)
67+ }
68+
69+ fn meta( registry: & mut $crate:: Registry <CtxT >) -> $crate:: meta:: MetaType {
70+ graphql_scalar!(
71+ @maybe_apply, $descr, description,
72+ registry. build_scalar_type:: <Self >( ) )
73+ . into_meta( )
74+ }
75+
76+ fn resolve(
77+ & $resolve_selfvar,
78+ _: Option <Vec <$crate:: Selection >>,
79+ _: & mut $crate:: Executor <CtxT >) -> $crate:: Value {
80+ $resolve_body
81+ }
4882 }
49- } ;
5083
51- (
52- @build_scalar_conv_impl,
53- $name: ty; [ $( $lifetime: tt) ,* ] ;
54- resolve( & $selfvar: ident) -> Value $body: block $( $rest: tt) *
55- ) => {
56- impl <$( $lifetime) ,* > $crate:: ToInputValue for $name {
57- fn to( & $selfvar) -> $crate:: InputValue {
58- $crate:: ToInputValue :: to( & $body)
84+ impl $crate:: ToInputValue for $name {
85+ fn to( & $resolve_selfvar) -> $crate:: InputValue {
86+ $crate:: ToInputValue :: to( & $resolve_body)
5987 }
6088 }
6189
62- graphql_scalar!( @build_scalar_conv_impl, $name; [ $( $lifetime) ,* ] ; $( $rest) * ) ;
90+ impl $crate:: FromInputValue for $name {
91+ fn from( $fiv_arg: & $crate:: InputValue ) -> $fiv_result {
92+ $fiv_body
93+ }
94+ }
6395 } ;
6496
97+ // No more items to parse
6598 (
66- @build_scalar_conv_impl,
67- $name: ty; [ $( $lifetime: tt) ,* ] ;
68- from_input_value( $arg: ident: & InputValue ) -> $result: ty $body: block
69- $( $rest: tt) *
99+ @parse,
100+ $meta: tt,
101+ $acc: tt,
70102 ) => {
71- impl <$( $lifetime) ,* > $crate:: FromInputValue for $name {
72- fn from( $arg: & $crate:: InputValue ) -> $result {
73- $body
74- }
75- }
76-
77- graphql_scalar!( @build_scalar_conv_impl, $name; [ $( $lifetime) ,* ] ; $( $rest) * ) ;
103+ graphql_scalar!( @generate, $meta, $acc ) ;
78104 } ;
79105
106+ // resolve(&self) -> Value { ... }
80107 (
81- @build_scalar_conv_impl,
82- $name: ty; $( $lifetime: tt) ,* ;
108+ @parse,
109+ $meta: tt,
110+ ( $_ignored: tt, $fiv: tt ) ,
111+ resolve( & $selfvar: ident) -> Value $body: block $( $rest: tt) *
83112 ) => {
113+ graphql_scalar!( @parse, $meta, ( ( $selfvar, $body) , $fiv ) , $( $rest) * ) ;
84114 } ;
85115
86- ( ( $( $lifetime: tt) ,* ) $name: ty as $outname: expr => { $( $items: tt ) * } ) => {
87- impl <$( $lifetime, ) * CtxT > $crate:: GraphQLType <CtxT > for $name {
88- fn name( ) -> Option <& ' static str > {
89- Some ( $outname)
90- }
91-
92- fn meta( registry: & mut $crate:: Registry <CtxT >) -> $crate:: meta:: MetaType {
93- registry. build_scalar_type:: <Self >( ) . into_meta( )
94- }
95-
96- graphql_scalar!( @build_scalar_resolver, $( $items) * ) ;
97- }
98-
99- graphql_scalar!( @build_scalar_conv_impl, $name; [ $( $lifetime) ,* ] ; $( $items) * ) ;
116+ // from_input_value(arg: &InputValue) -> ... { ... }
117+ (
118+ @parse,
119+ $meta: tt,
120+ ( $resolve: tt, $_ignored: tt ) ,
121+ from_input_value( $arg: ident: & InputValue ) -> $result: ty $body: block $( $rest: tt) *
122+ ) => {
123+ graphql_scalar!( @parse, $meta, ( $resolve, ( $arg, $result, $body ) ) , $( $rest) * ) ;
100124 } ;
101125
102- ( <$( $lifetime: tt) ,* > $name: ty as $outname: tt { $( $items: tt ) * } ) => {
103- graphql_scalar!( ( $( $lifetime) ,* ) $name as $outname => { $( $items ) * } ) ;
126+ // description: <description>
127+ (
128+ @parse,
129+ ( $name: ty, $outname: tt, $_ignored: tt ) ,
130+ $acc: tt,
131+ description: $descr: tt $( $rest: tt) *
132+ ) => {
133+ graphql_scalar!( @parse, ( $name, $outname, $descr ) , $acc, $( $rest) * ) ;
104134 } ;
105135
136+ // Entry point:
137+ // RustName as "GraphQLName" { ... }
106138 ( $name: ty as $outname: tt { $( $items: tt ) * } ) => {
107- graphql_scalar!( ( ) $name as $outname => { $( $items ) * } ) ;
108- }
139+ graphql_scalar!( @parse, ( $name, $outname, None ) , ( None , None ) , $( $items) * ) ;
140+ } ;
141+
142+ // Entry point
143+ // RustName { ... }
144+ ( $name: ty { $( $items: tt ) * } ) => {
145+ graphql_scalar!( @parse, ( $name, ( stringify!( $name) ) , None ) , ( None , None ) , $( $items) * ) ;
146+ } ;
109147}
0 commit comments