dynamic_graphql/types/
common.rs

1use std::borrow::Cow;
2
3use async_graphql::MaybeUndefined;
4use async_graphql::dynamic;
5
6use crate::registry::Registry;
7use crate::type_ref_builder::TypeRefBuilder;
8use crate::types::GetInputTypeRef;
9use crate::types::GetOutputTypeRef;
10use crate::types::InputTypeName;
11use crate::types::OutputTypeName;
12use crate::types::Register;
13use crate::types::TypeName;
14
15impl<T> Register for &T
16where
17    T: Register + 'static,
18{
19    fn register(registry: Registry) -> Registry {
20        registry.register::<T>()
21    }
22}
23
24impl<T> TypeName for &'_ T
25where
26    T: TypeName + 'static,
27{
28    fn get_type_name() -> Cow<'static, str> {
29        <T as TypeName>::get_type_name()
30    }
31}
32
33impl<T: OutputTypeName + 'static> OutputTypeName for &T {}
34
35impl<T: Register + Clone + 'static> Register for Cow<'_, T> {
36    fn register(registry: Registry) -> Registry {
37        registry.register::<T>()
38    }
39}
40impl<T: OutputTypeName + Clone + 'static> TypeName for Cow<'_, T> {
41    fn get_type_name() -> Cow<'static, str> {
42        <T as TypeName>::get_type_name()
43    }
44}
45
46impl<T: OutputTypeName + Clone + 'static> OutputTypeName for Cow<'_, T> {}
47
48impl Register for String {}
49impl TypeName for String {
50    fn get_type_name() -> Cow<'static, str> {
51        dynamic::TypeRef::STRING.into()
52    }
53}
54
55impl InputTypeName for String {}
56
57impl OutputTypeName for String {}
58
59impl Register for &str {}
60impl TypeName for &str {
61    fn get_type_name() -> Cow<'static, str> {
62        dynamic::TypeRef::STRING.into()
63    }
64}
65
66impl InputTypeName for &str {}
67
68impl OutputTypeName for &str {}
69
70impl TypeName for str {
71    fn get_type_name() -> Cow<'static, str> {
72        dynamic::TypeRef::STRING.into()
73    }
74}
75
76impl Register for str {}
77impl InputTypeName for str {}
78
79impl OutputTypeName for str {}
80
81impl Register for async_graphql::ID {}
82impl TypeName for async_graphql::ID {
83    fn get_type_name() -> Cow<'static, str> {
84        dynamic::TypeRef::ID.into()
85    }
86}
87
88impl InputTypeName for async_graphql::ID {}
89
90impl OutputTypeName for async_graphql::ID {}
91
92impl Register for bool {}
93impl TypeName for bool {
94    fn get_type_name() -> Cow<'static, str> {
95        dynamic::TypeRef::BOOLEAN.into()
96    }
97}
98
99impl InputTypeName for bool {}
100
101impl OutputTypeName for bool {}
102
103impl Register for f32 {}
104impl TypeName for f32 {
105    fn get_type_name() -> Cow<'static, str> {
106        dynamic::TypeRef::FLOAT.into()
107    }
108}
109
110impl InputTypeName for f32 {}
111
112impl OutputTypeName for f32 {}
113
114impl Register for f64 {}
115impl TypeName for f64 {
116    fn get_type_name() -> Cow<'static, str> {
117        dynamic::TypeRef::FLOAT.into()
118    }
119}
120
121impl InputTypeName for f64 {}
122
123impl OutputTypeName for f64 {}
124
125macro_rules! int_output_value {
126    ($($t:ty),*) => {
127        $(
128            impl Register for $t {}
129            impl TypeName for $t {
130                fn get_type_name() -> Cow<'static, str> {
131                    dynamic::TypeRef::INT.into()
132                }
133            }
134            impl InputTypeName for $t {}
135            impl OutputTypeName for $t {}
136        )*
137    };
138}
139
140int_output_value!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
141
142impl<T> Register for Option<T>
143where
144    T: Register + 'static,
145{
146    fn register(registry: Registry) -> Registry {
147        registry.register::<T>()
148    }
149}
150impl<T> Register for MaybeUndefined<T>
151where
152    T: Register + 'static,
153{
154    fn register(registry: Registry) -> Registry {
155        registry.register::<T>()
156    }
157}
158impl<T, E> Register for Result<T, E>
159where
160    T: Register + 'static,
161{
162    fn register(registry: Registry) -> Registry {
163        registry.register::<T>()
164    }
165}
166impl<T> Register for Vec<T>
167where
168    T: Register + 'static,
169{
170    fn register(registry: Registry) -> Registry {
171        registry.register::<T>()
172    }
173}
174impl<T> Register for &[T]
175where
176    T: Register + 'static,
177{
178    fn register(registry: Registry) -> Registry {
179        registry.register::<T>()
180    }
181}
182
183impl<T, E> GetOutputTypeRef for Result<T, E>
184where
185    T: GetOutputTypeRef,
186{
187    #[inline]
188    fn get_output_type_ref() -> TypeRefBuilder {
189        T::get_output_type_ref()
190    }
191}
192
193impl<T: OutputTypeName> GetOutputTypeRef for T {
194    #[inline]
195    fn get_output_type_ref() -> TypeRefBuilder {
196        TypeRefBuilder::NamedNN(T::get_output_type_name().to_string())
197    }
198}
199
200impl<T: GetOutputTypeRef> GetOutputTypeRef for Option<T> {
201    #[inline]
202    fn get_output_type_ref() -> TypeRefBuilder {
203        let t = T::get_output_type_ref();
204        t.optional()
205    }
206}
207
208impl<T: GetOutputTypeRef> GetOutputTypeRef for Vec<T> {
209    #[inline]
210    fn get_output_type_ref() -> TypeRefBuilder {
211        T::get_output_type_ref().list()
212    }
213}
214
215impl<T: GetOutputTypeRef> GetOutputTypeRef for &[T] {
216    #[inline]
217    fn get_output_type_ref() -> TypeRefBuilder {
218        T::get_output_type_ref().list()
219    }
220}
221
222impl<T: InputTypeName> GetInputTypeRef for T {
223    #[inline]
224    fn get_input_type_ref() -> TypeRefBuilder {
225        TypeRefBuilder::NamedNN(T::get_input_type_name().to_string())
226    }
227}
228
229impl<T: GetInputTypeRef, E> GetInputTypeRef for Result<T, E> {
230    #[inline]
231    fn get_input_type_ref() -> TypeRefBuilder {
232        T::get_input_type_ref().optional()
233    }
234}
235
236impl<T: GetInputTypeRef> GetInputTypeRef for Option<T> {
237    #[inline]
238    fn get_input_type_ref() -> TypeRefBuilder {
239        T::get_input_type_ref().optional()
240    }
241}
242
243impl<T: GetInputTypeRef> GetInputTypeRef for MaybeUndefined<T> {
244    #[inline]
245    fn get_input_type_ref() -> TypeRefBuilder {
246        T::get_input_type_ref().optional()
247    }
248}
249
250impl<T: GetInputTypeRef> GetInputTypeRef for Vec<T> {
251    #[inline]
252    fn get_input_type_ref() -> TypeRefBuilder {
253        T::get_input_type_ref().list()
254    }
255}
256impl<T: GetInputTypeRef> GetInputTypeRef for &[T] {
257    #[inline]
258    fn get_input_type_ref() -> TypeRefBuilder {
259        T::get_input_type_ref().list()
260    }
261}
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266
267    #[test]
268    fn test_get_output_type_ref() {
269        let type_ref: dynamic::TypeRef = <String as GetOutputTypeRef>::get_output_type_ref().into();
270        assert_eq!(type_ref.to_string(), "String!");
271        let type_ref: dynamic::TypeRef =
272            <Option<String> as GetOutputTypeRef>::get_output_type_ref().into();
273        assert_eq!(type_ref.to_string(), "String");
274        let type_ref: dynamic::TypeRef =
275            <Vec<String> as GetOutputTypeRef>::get_output_type_ref().into();
276        assert_eq!(type_ref.to_string(), "[String!]!");
277        let type_ref: dynamic::TypeRef =
278            <Option<Vec<String>> as GetOutputTypeRef>::get_output_type_ref().into();
279        assert_eq!(type_ref.to_string(), "[String!]");
280        let type_ref: dynamic::TypeRef =
281            <Vec<Option<String>> as GetOutputTypeRef>::get_output_type_ref().into();
282        assert_eq!(type_ref.to_string(), "[String]!");
283        let type_ref: dynamic::TypeRef =
284            <Option<Vec<Option<String>>> as GetOutputTypeRef>::get_output_type_ref().into();
285        assert_eq!(type_ref.to_string(), "[String]");
286        let type_ref: dynamic::TypeRef =
287            <&[String] as GetOutputTypeRef>::get_output_type_ref().into();
288        assert_eq!(type_ref.to_string(), "[String!]!");
289        let type_ref: dynamic::TypeRef =
290            <Option<&[String]> as GetOutputTypeRef>::get_output_type_ref().into();
291        assert_eq!(type_ref.to_string(), "[String!]");
292        let type_ref: dynamic::TypeRef =
293            <&[Option<String>] as GetOutputTypeRef>::get_output_type_ref().into();
294        assert_eq!(type_ref.to_string(), "[String]!");
295        let type_ref: dynamic::TypeRef =
296            <Option<&[Option<String>]> as GetOutputTypeRef>::get_output_type_ref().into();
297        assert_eq!(type_ref.to_string(), "[String]");
298    }
299
300    #[test]
301    fn test_get_input_type_ref() {
302        let type_ref: dynamic::TypeRef = <String as GetInputTypeRef>::get_input_type_ref().into();
303        assert_eq!(type_ref.to_string(), "String!");
304        let type_ref: dynamic::TypeRef =
305            <Option<String> as GetInputTypeRef>::get_input_type_ref().into();
306        assert_eq!(type_ref.to_string(), "String");
307        let type_ref: dynamic::TypeRef =
308            <Vec<String> as GetInputTypeRef>::get_input_type_ref().into();
309        assert_eq!(type_ref.to_string(), "[String!]!");
310        let type_ref: dynamic::TypeRef =
311            <Option<Vec<String>> as GetInputTypeRef>::get_input_type_ref().into();
312        assert_eq!(type_ref.to_string(), "[String!]");
313        let type_ref: dynamic::TypeRef =
314            <Vec<Option<String>> as GetInputTypeRef>::get_input_type_ref().into();
315        assert_eq!(type_ref.to_string(), "[String]!");
316        let type_ref: dynamic::TypeRef =
317            <Option<Vec<Option<String>>> as GetInputTypeRef>::get_input_type_ref().into();
318        assert_eq!(type_ref.to_string(), "[String]");
319        let type_ref: dynamic::TypeRef =
320            <&[String] as GetInputTypeRef>::get_input_type_ref().into();
321        assert_eq!(type_ref.to_string(), "[String!]!");
322        let type_ref: dynamic::TypeRef =
323            <Option<&[String]> as GetInputTypeRef>::get_input_type_ref().into();
324        assert_eq!(type_ref.to_string(), "[String!]");
325        let type_ref: dynamic::TypeRef =
326            <&[Option<String>] as GetInputTypeRef>::get_input_type_ref().into();
327        assert_eq!(type_ref.to_string(), "[String]!");
328        let type_ref: dynamic::TypeRef =
329            <Option<&[Option<String>]> as GetInputTypeRef>::get_input_type_ref().into();
330        assert_eq!(type_ref.to_string(), "[String]");
331    }
332}