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 }
174 })
175 }
176
177 fn parse(
178 value: ::std::option::Option<$crate::Value>,
179 ) -> $crate::InputValueResult<Self> {
180 <$ty as $crate::ScalarType>::parse(value.unwrap_or_default())
181 }
182
183 fn to_value(&self) -> $crate::Value {
184 <$ty as $crate::ScalarType>::to_value(self)
185 }
186
187 fn as_raw_value(&self) -> ::std::option::Option<&Self::RawValueType> {
188 ::std::option::Option::Some(self)
189 }
190 }
191
192 $crate::scalar_internal_output!($ty, $name, $desc, $specified_by_url);
193 };
194}
195
196#[cfg(feature = "boxed-trait")]
197#[macro_export]
198#[doc(hidden)]
199macro_rules! scalar_internal_output {
200 ($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
201 #[$crate::async_trait::async_trait]
202 impl $crate::OutputType for $ty {
203 fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
204 ::std::borrow::Cow::Borrowed($name)
205 }
206
207 fn create_type_info(
208 registry: &mut $crate::registry::Registry,
209 ) -> ::std::string::String {
210 registry.create_output_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| {
211 $crate::registry::MetaType::Scalar {
212 name: ::std::borrow::ToOwned::to_owned($name),
213 description: $desc,
214 is_valid: ::std::option::Option::Some(::std::sync::Arc::new(|value| {
215 <$ty as $crate::ScalarType>::is_valid(value)
216 })),
217 visible: ::std::option::Option::None,
218 inaccessible: false,
219 tags: ::std::default::Default::default(),
220 specified_by_url: $specified_by_url,
221 directive_invocations: ::std::vec::Vec::new(),
222 }
223 })
224 }
225
226 async fn resolve(
227 &self,
228 _: &$crate::ContextSelectionSet<'_>,
229 _field: &$crate::Positioned<$crate::parser::types::Field>,
230 ) -> $crate::ServerResult<$crate::Value> {
231 ::std::result::Result::Ok($crate::ScalarType::to_value(self))
232 }
233 }
234 };
235}
236
237#[cfg(not(feature = "boxed-trait"))]
238#[macro_export]
239#[doc(hidden)]
240macro_rules! scalar_internal_output {
241 ($ty:ty, $name:expr, $desc:expr, $specified_by_url:expr) => {
242 impl $crate::OutputType for $ty {
243 fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
244 ::std::borrow::Cow::Borrowed($name)
245 }
246
247 fn create_type_info(
248 registry: &mut $crate::registry::Registry,
249 ) -> ::std::string::String {
250 registry.create_output_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| {
251 $crate::registry::MetaType::Scalar {
252 name: ::std::borrow::ToOwned::to_owned($name),
253 description: $desc,
254 is_valid: ::std::option::Option::Some(::std::sync::Arc::new(|value| {
255 <$ty as $crate::ScalarType>::is_valid(value)
256 })),
257 visible: ::std::option::Option::None,
258 inaccessible: false,
259 tags: ::std::default::Default::default(),
260 specified_by_url: $specified_by_url,
261 directive_invocations: ::std::vec::Vec::new(),
262 }
263 })
264 }
265
266 async fn resolve(
267 &self,
268 _: &$crate::ContextSelectionSet<'_>,
269 _field: &$crate::Positioned<$crate::parser::types::Field>,
270 ) -> $crate::ServerResult<$crate::Value> {
271 ::std::result::Result::Ok($crate::ScalarType::to_value(self))
272 }
273 }
274 };
275}