dynamic_graphql/
resolve.rs1use std::borrow::Cow;
2
3use crate::Context;
4use crate::Error;
5use crate::FieldValue;
6use crate::ID;
7use crate::Result;
8
9pub trait ResolveRef<'a> {
10 fn resolve_ref(&'a self, ctx: &Context) -> Result<Option<FieldValue<'a>>>;
11}
12
13pub trait ResolveOwned<'a> {
14 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>>;
15}
16
17pub trait Resolve<'a> {
18 fn resolve(self, ctx: &Context) -> Result<Option<FieldValue<'a>>>;
19}
20
21mod resolve_ref {
22 use super::*;
23 impl<'a, T> ResolveRef<'a> for Option<T>
25 where
26 &'a T: Resolve<'a> + 'a,
27 {
28 #[inline]
29 fn resolve_ref(&'a self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
30 match self {
31 None => Ok(None),
32 Some(value) => value.resolve(ctx),
33 }
34 }
35 }
36
37 impl<'a, T> ResolveRef<'a> for Vec<T>
39 where
40 &'a T: Resolve<'a> + 'a,
41 {
42 fn resolve_ref(&'a self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
43 let iter = self.iter();
44 let items = iter.enumerate().map(|(index, item)| {
45 let ctx_idx = ctx.with_index(index);
46 match item.resolve(&ctx_idx) {
47 Ok(Some(value)) => value,
48 _ => FieldValue::NULL,
49 }
50 });
51 Ok(Some(FieldValue::list(items)))
52 }
53 }
54 impl<'a> ResolveRef<'a> for ID {
56 #[inline]
57 fn resolve_ref(&self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
58 Ok(Some(FieldValue::value(self.0.to_owned())))
59 }
60 }
61 impl<'a> ResolveRef<'a> for &str {
63 #[inline]
64 fn resolve_ref(&'a self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
65 Ok(Some(FieldValue::value(self.to_string())))
66 }
67 }
68}
69mod resolve_own {
70 use super::*;
71 impl<'a, T> ResolveOwned<'a> for &'a T
73 where
74 T: ResolveRef<'a>,
75 {
76 #[inline]
77 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
78 self.resolve_ref(ctx)
79 }
80 }
81 impl<'a, T> ResolveOwned<'a> for Cow<'a, T>
83 where
84 T: Clone + Resolve<'a>,
85 &'a T: Resolve<'a>,
86 {
87 #[inline]
88 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
89 match self {
90 Cow::Owned(value) => value.resolve(ctx),
91 Cow::Borrowed(value) => value.resolve(ctx),
92 }
93 }
94 }
95 impl<'a, T> ResolveOwned<'a> for Option<T>
97 where
98 T: Resolve<'a>,
99 {
100 #[inline]
101 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
102 match self {
103 None => Ok(None),
104 Some(value) => value.resolve(ctx),
105 }
106 }
107 }
108
109 impl<'a, T, E> ResolveOwned<'a> for Result<T, E>
111 where
112 T: Resolve<'a>,
113 E: Into<Error>,
114 {
115 #[inline]
116 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
117 match self {
118 Ok(value) => value.resolve(ctx),
119 Err(err) => Err(err.into()),
120 }
121 }
122 }
123
124 impl<'a, T> ResolveOwned<'a> for Vec<T>
126 where
127 T: Resolve<'a>,
128 {
129 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
130 let iter = self.into_iter();
131 let items = iter.enumerate().map(|(index, item)| {
132 let ctx_idx = ctx.with_index(index);
133 match item.resolve(&ctx_idx) {
134 Ok(Some(value)) => value,
135 _ => FieldValue::NULL,
136 }
137 });
138 Ok(Some(FieldValue::list(items)))
139 }
140 }
141
142 impl<'a, T> ResolveOwned<'a> for &'a [T]
144 where
145 &'a T: Resolve<'a>,
146 {
147 fn resolve_owned(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
148 let iter = self.iter();
149 let items = iter.enumerate().map(|(index, item)| {
150 let ctx_idx = ctx.with_index(index);
151 match item.resolve(&ctx_idx) {
152 Ok(Some(value)) => value,
153 _ => FieldValue::NULL,
154 }
155 });
156 Ok(Some(FieldValue::list(items)))
157 }
158 }
159
160 impl<'a> ResolveOwned<'a> for ID {
162 #[inline]
163 fn resolve_owned(self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
164 Ok(Some(FieldValue::value(self.0)))
165 }
166 }
167
168 impl<'a> ResolveOwned<'a> for &str {
170 #[inline]
171 fn resolve_owned(self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
172 Ok(Some(FieldValue::value(self.to_string())))
173 }
174 }
175}
176
177impl<'a, T: ResolveOwned<'a>> Resolve<'a> for T {
179 #[inline]
180 fn resolve(self, ctx: &Context) -> Result<Option<FieldValue<'a>>> {
181 self.resolve_owned(ctx)
182 }
183}
184
185macro_rules! resolves {
186 ($($ty:ident),*) => {
187 $(
188 impl <'a> ResolveOwned<'a> for $ty {
189 #[inline]
190 fn resolve_owned(self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
191 Ok(Some(FieldValue::value(self)))
192 }
193 }
194 impl <'a> ResolveRef<'a> for $ty {
195 #[inline]
196 fn resolve_ref(&self, _ctx: &Context) -> Result<Option<FieldValue<'a>>> {
197 Ok(Some(FieldValue::value(self.to_owned())))
198 }
199 }
200 )*
201 };
202}
203
204resolves!(
205 String, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, bool, f32, f64
206);