@@ -3,13 +3,31 @@ use query::QueryContext;
33use selection:: Selection ;
44use std:: cell:: Cell ;
55
6+ /// Represents which type a fragment is defined on. This is the type mentioned in the fragment's `on` clause.
7+ #[ derive( Debug , PartialEq ) ]
8+ pub ( crate ) enum FragmentTarget < ' context > {
9+ Object ( & ' context crate :: objects:: GqlObject < ' context > ) ,
10+ Interface ( & ' context crate :: interfaces:: GqlInterface < ' context > ) ,
11+ Union ( & ' context crate :: unions:: GqlUnion < ' context > ) ,
12+ }
13+
14+ impl < ' context > FragmentTarget < ' context > {
15+ pub ( crate ) fn name ( & self ) -> & str {
16+ match self {
17+ FragmentTarget :: Object ( obj) => obj. name ,
18+ FragmentTarget :: Interface ( iface) => iface. name ,
19+ FragmentTarget :: Union ( unn) => unn. name ,
20+ }
21+ }
22+ }
23+
624/// Represents a fragment extracted from a query document.
725#[ derive( Debug , PartialEq ) ]
826pub ( crate ) struct GqlFragment < ' query > {
927 /// The name of the fragment, matching one-to-one with the name in the GraphQL query document.
1028 pub name : & ' query str ,
1129 /// The `on` clause of the fragment.
12- pub on : & ' query str ,
30+ pub on : FragmentTarget < ' query > ,
1331 /// The selected fields.
1432 pub selection : Selection < ' query > ,
1533 /// Whether the fragment is used in the current query
@@ -19,16 +37,20 @@ pub(crate) struct GqlFragment<'query> {
1937impl < ' query > GqlFragment < ' query > {
2038 /// Generate all the Rust code required by the fragment's object selection.
2139 pub ( crate ) fn to_rust ( & self , context : & QueryContext ) -> Result < TokenStream , :: failure:: Error > {
22- if let Some ( obj ) = context . schema . objects . get ( & self . on ) {
23- obj . response_for_selection ( context , & self . selection , & self . name )
24- } else if let Some ( iface ) = context . schema . interfaces . get ( & self . on ) {
25- iface . response_for_selection ( context , & self . selection , & self . name )
26- } else {
27- Err ( format_err ! (
28- "Fragment {} is defined on unknown type: {}" ,
29- self . name ,
30- self . on
31- ) ) ?
40+ match self . on {
41+ FragmentTarget :: Object ( obj ) => {
42+ obj . response_for_selection ( context , & self . selection , & self . name )
43+ }
44+ FragmentTarget :: Interface ( iface ) => {
45+ iface . response_for_selection ( context , & self . selection , & self . name )
46+ }
47+ FragmentTarget :: Union ( _ ) => {
48+ unreachable ! ( "Wrong code path. Fragment on unions are treated differently." )
49+ }
3250 }
3351 }
52+
53+ pub ( crate ) fn is_recursive ( & self ) -> bool {
54+ self . selection . contains_fragment ( & self . name )
55+ }
3456}
0 commit comments