async_graphql/resolver_utils/
scalar.rs1use crate::{InputValueResult, Value};
2
3pub trait ScalarType: Sized + Send {
31 fn parse(value: Value) -> InputValueResult<Self>;
33
34 fn is_valid(_value: &Value) -> bool {
39 true
40 }
41
42 fn to_value(&self) -> Value;
44}
45
46#[macro_export]
99macro_rules! scalar {
100 ($ty:ty, $name:literal, $desc:literal, $specified_by_url:literal) => {
101 $crate::scalar_internal!(
102 $ty,
103 $name,
104 ::std::option::Option::Some(::std::string::ToString::to_string($desc)),
105 ::std::option::Option::Some(::std::string::ToString::to_string($specified_by_url))
106 );
107 };
108
109 ($ty:ty, $name:literal, $desc:literal) => {
110 $crate::scalar_internal!(
111 $ty,
112 $name,
113 ::std::option::Option::Some(::std::string::ToString::to_string($desc)),
114 ::std::option::Option::None
115 );
116 };
117
118 ($ty:ty, $name:literal) => {
119 $crate::scalar_internal!(
120 $ty,
121 $name,
122 ::std::option::Option::None,
123 ::std::option::Option::None
124 );
125 };
126
127 ($ty:ty) => {
128 $crate::scalar_internal!(
129 $ty,
130 ::std::stringify!($ty),
131 ::std::option::Option::None,
132 ::std::option::Option::None
133 );
134 };
135}
136
137#[macro_export]
138#[doc(hidden)]
139macro_rules! scalar_internal {
140 ($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
141 impl $crate::ScalarType for $ty {
142 fn parse(value: $crate::Value) -> $crate::InputValueResult<Self> {
143 ::std::result::Result::Ok($crate::from_value(value)?)
144 }
145
146 fn to_value(&self) -> $crate::Value {
147 $crate::to_value(self).unwrap_or_else(|_| $crate::Value::Null)
148 }
149 }
150
151 impl $crate::InputType for $ty {
152 type RawValueType = Self;
153
154 fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
155 ::std::borrow::Cow::Borrowed($name)
156 }
157
158 fn create_type_info(
159 registry: &mut $crate::registry::Registry,
160 ) -> ::std::string::String {
161 registry.create_input_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| {
162 $crate::registry::MetaType::Scalar {
163 name: ::std::borrow::ToOwned::to_owned($name),
164 description: $desc,
165 is_valid: ::std::option::Option::Some(::std::sync::Arc::new(|value| {
166 <$ty as $crate::ScalarType>::is_valid(value)
167 })),
168 visible: ::std::option::Option::None,
169 inaccessible: false,
170 tags: ::std::default::Default::default(),
171 specified_by_url: $specified_by_url,
172 directive_invocations: ::std::vec::Vec::new(),
173 requires_scopes: ::std::vec::Vec::new(),
174 }
175 })
176 }
177
178 fn parse(
179 value: ::std::option::Option<$crate::Value>,
180 ) -> $crate::InputValueResult<Self> {
181 <$ty as $crate::ScalarType>::parse(value.unwrap_or_default())
182 }
183
184 fn to_value(&self) -> $crate::Value {
185 <$ty as $crate::ScalarType>::to_value(self)
186 }
187
188 fn as_raw_value(&self) -> ::std::option::Option<&Self::RawValueType> {
189 ::std::option::Option::Some(self)
190 }
191 }
192
193 $crate::scalar_internal_output!($ty, $name, $desc, $specified_by_url);
194 };
195}
196
197#[cfg(feature = "boxed-trait")]
198#[macro_export]
199#[doc(hidden)]
200macro_rules! scalar_internal_output {
201 ($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
202 #[$crate::async_trait::async_trait]
203 impl $crate::OutputType for $ty {
204 fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
205 ::std::borrow::Cow::Borrowed($name)
206 }
207
208 fn create_type_info(
209 registry: &mut $crate::registry::Registry,
210 ) -> ::std::string::String {
211 registry.create_output_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| {
212 $crate::registry::MetaType::Scalar {
213 name: ::std::borrow::ToOwned::to_owned($name),
214 description: $desc,
215 is_valid: ::std::option::Option::Some(::std::sync::Arc::new(|value| {
216 <$ty as $crate::ScalarType>::is_valid(value)
217 })),
218 visible: ::std::option::Option::None,
219 inaccessible: false,
220 tags: ::std::default::Default::default(),
221 specified_by_url: $specified_by_url,
222 directive_invocations: ::std::vec::Vec::new(),
223 requires_scopes: ::std::vec::Vec::new(),
224 }
225 })
226 }
227
228 async fn resolve(
229 &self,
230 _: &$crate::ContextSelectionSet<'_>,
231 _field: &$crate::Positioned<$crate::parser::types::Field>,
232 ) -> $crate::ServerResult<$crate::Value> {
233 ::std::result::Result::Ok($crate::ScalarType::to_value(self))
234 }
235 }
236 };
237}
238
239#[cfg(not(feature = "boxed-trait"))]
240#[macro_export]
241#[doc(hidden)]
242macro_rules! scalar_internal_output {
243 ($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
244 impl $crate::OutputType for $ty {
245 fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
246 ::std::borrow::Cow::Borrowed($name)
247 }
248
249 fn create_type_info(
250 registry: &mut $crate::registry::Registry,
251 ) -> ::std::string::String {
252 registry.create_output_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| {
253 $crate::registry::MetaType::Scalar {
254 name: ::std::borrow::ToOwned::to_owned($name),
255 description: $desc,
256 is_valid: ::std::option::Option::Some(::std::sync::Arc::new(|value| {
257 <$ty as $crate::ScalarType>::is_valid(value)
258 })),
259 visible: ::std::option::Option::None,
260 inaccessible: false,
261 tags: ::std::default::Default::default(),
262 specified_by_url: $specified_by_url,
263 directive_invocations: ::std::vec::Vec::new(),
264 requires_scopes: ::std::vec::Vec::new(),
265 }
266 })
267 }
268
269 async fn resolve(
270 &self,
271 _: &$crate::ContextSelectionSet<'_>,
272 _field: &$crate::Positioned<$crate::parser::types::Field>,
273 ) -> $crate::ServerResult<$crate::Value> {
274 ::std::result::Result::Ok($crate::ScalarType::to_value(self))
275 }
276 }
277 };
278}