wundergraph/
graphql_type.rs1use crate::query_builder::selection::offset::ApplyOffset;
2use crate::query_builder::selection::LoadingHandler;
3use crate::scalar::WundergraphScalarValue;
4use diesel::backend::Backend;
5use diesel::query_builder::QueryFragment;
6use diesel::QuerySource;
7use juniper::{meta, GraphQLType, Registry};
8use std::marker::PhantomData;
9
10#[derive(Debug)]
13pub struct GraphqlWrapper<T, DB, Ctx>(T, PhantomData<(DB, Ctx)>);
14
15impl<T, DB, Ctx> GraphQLType<WundergraphScalarValue> for GraphqlWrapper<T, DB, Ctx>
16where
17 DB: Backend + ApplyOffset + 'static,
18 T::Table: 'static,
19 <T::Table as QuerySource>::FromClause: QueryFragment<DB>,
20 T: LoadingHandler<DB, Ctx>,
21 T::FieldList: WundergraphGraphqlHelper<T, DB, Ctx>,
22 DB::QueryBuilder: Default,
23{
24 type Context = ();
25 type TypeInfo = ();
26
27 fn name(_info: &Self::TypeInfo) -> Option<&str> {
28 Some(T::TYPE_NAME)
29 }
30
31 fn meta<'r>(
32 _info: &Self::TypeInfo,
33 registry: &mut Registry<'r, WundergraphScalarValue>,
34 ) -> meta::MetaType<'r, WundergraphScalarValue>
35 where
36 WundergraphScalarValue: 'r,
37 {
38 <T::FieldList as WundergraphGraphqlHelper<T, DB, Ctx>>::object_meta::<Self>(
39 T::FIELD_NAMES,
40 registry,
41 )
42 }
43}
44
45#[doc(hidden)]
46pub trait WundergraphGraphqlMapper<DB, Ctx> {
47 type GraphQLType: GraphQLType<WundergraphScalarValue, TypeInfo = ()>;
48
49 fn register_arguments<'r>(
50 _registry: &mut Registry<'r, WundergraphScalarValue>,
51 field: meta::Field<'r, WundergraphScalarValue>,
52 ) -> meta::Field<'r, WundergraphScalarValue> {
53 field
54 }
55}
56
57impl<T, DB, Ctx> WundergraphGraphqlMapper<DB, Ctx> for T
58where
59 T: GraphQLType<WundergraphScalarValue, TypeInfo = ()>,
60{
61 type GraphQLType = Self;
62}
63
64#[doc(hidden)]
65pub trait WundergraphGraphqlHelper<L, DB, Ctx> {
66 fn object_meta<'r, T>(
67 names: &[&str],
68 registry: &mut Registry<'r, WundergraphScalarValue>,
69 ) -> meta::MetaType<'r, WundergraphScalarValue>
70 where
71 T: GraphQLType<WundergraphScalarValue, TypeInfo = ()>;
72}
73
74macro_rules! wundergraph_graphql_helper_impl {
75 ($(
76 $Tuple:tt {
77 $(($idx:tt) -> $T:ident, $ST: ident, $TT: ident,) +
78 }
79 )+) => {
80 $(
81 impl<$($T,)* Loading, Back, Ctx> WundergraphGraphqlHelper<Loading, Back, Ctx> for ($($T,)*)
82 where $($T: WundergraphGraphqlMapper<Back, Ctx>,)*
83 Back: Backend + ApplyOffset + 'static,
84 Loading::Table: 'static,
85 <Loading::Table as QuerySource>::FromClause: QueryFragment<Back>,
86 Loading: LoadingHandler<Back, Ctx>,
87 Back::QueryBuilder: Default,
88 {
89 fn object_meta<'r, Type>(
90 names: &[&str],
91 registry: &mut Registry<'r, WundergraphScalarValue>,
92 ) -> meta::MetaType<'r, WundergraphScalarValue>
93 where Type: GraphQLType<WundergraphScalarValue, TypeInfo = ()>
94 {
95 let fields = [
96 $({
97 let mut field = registry.field::<<$T as WundergraphGraphqlMapper<Back, Ctx>>::GraphQLType>(names[$idx], &());
98 field = <$T as WundergraphGraphqlMapper<Back, Ctx>>::register_arguments(registry, field);
99 if let Some(doc) = Loading::field_description($idx) {
100 field = field.description(doc);
101 }
102 if let Some(deprecated) = Loading::field_deprecation($idx) {
103 field = field.deprecated(deprecated);
104 }
105 field
106 },)*
107 ];
108 let mut ty = registry.build_object_type::<Type>(
109 &(),
110 &fields,
111 );
112 if let Some(doc) = Loading::TYPE_DESCRIPTION {
113 ty = ty.description(doc);
114 }
115 meta::MetaType::Object(ty)
116 }
117 }
118 )*
119 };
120}
121
122__diesel_for_each_tuple!(wundergraph_graphql_helper_impl);