1use std::{char, fmt, marker::PhantomData, ops::Deref, rc::Rc, thread::JoinHandle, u32};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 ast::{InputValue, Selection, ToInputValue},
7 executor::{ExecutionResult, Executor, Registry},
8 graphql_scalar,
9 macros::reflect,
10 parser::{LexerError, ParseError, ScalarToken, Token},
11 schema::meta::MetaType,
12 types::{
13 async_await::GraphQLValueAsync,
14 base::{GraphQLType, GraphQLValue},
15 subscriptions::GraphQLSubscriptionValue,
16 },
17 value::{ParseScalarResult, ScalarValue, Value},
18 GraphQLScalar,
19};
20
21#[derive(Clone, Debug, Deserialize, Eq, GraphQLScalar, PartialEq, Serialize)]
25#[graphql(parse_token(String, i32))]
26pub struct ID(String);
27
28impl ID {
29 fn to_output<S: ScalarValue>(&self) -> Value<S> {
30 Value::scalar(self.0.clone())
31 }
32
33 fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<Self, String> {
34 v.as_string_value()
35 .map(str::to_owned)
36 .or_else(|| v.as_int_value().as_ref().map(ToString::to_string))
37 .map(Self)
38 .ok_or_else(|| format!("Expected `String` or `Int`, found: {v}"))
39 }
40}
41
42impl From<String> for ID {
43 fn from(s: String) -> ID {
44 ID(s)
45 }
46}
47
48impl ID {
49 pub fn new<S: Into<String>>(value: S) -> Self {
51 ID(value.into())
52 }
53}
54
55impl Deref for ID {
56 type Target = str;
57
58 fn deref(&self) -> &str {
59 &self.0
60 }
61}
62
63impl fmt::Display for ID {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 self.0.fmt(f)
66 }
67}
68
69#[graphql_scalar(with = impl_string_scalar)]
70type String = std::string::String;
71
72mod impl_string_scalar {
73 use super::*;
74
75 pub(super) fn to_output<S: ScalarValue>(v: &str) -> Value<S> {
76 Value::scalar(v.to_owned())
77 }
78
79 pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<String, String> {
80 v.as_string_value()
81 .map(str::to_owned)
82 .ok_or_else(|| format!("Expected `String`, found: {v}"))
83 }
84
85 pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
86 if let ScalarToken::String(value) = value {
87 let mut ret = String::with_capacity(value.len());
88 let mut char_iter = value.chars();
89 while let Some(ch) = char_iter.next() {
90 match ch {
91 '\\' => match char_iter.next() {
92 Some('"') => {
93 ret.push('"');
94 }
95 Some('/') => {
96 ret.push('/');
97 }
98 Some('n') => {
99 ret.push('\n');
100 }
101 Some('r') => {
102 ret.push('\r');
103 }
104 Some('t') => {
105 ret.push('\t');
106 }
107 Some('\\') => {
108 ret.push('\\');
109 }
110 Some('f') => {
111 ret.push('\u{000c}');
112 }
113 Some('b') => {
114 ret.push('\u{0008}');
115 }
116 Some('u') => {
117 ret.push(parse_unicode_codepoint(&mut char_iter)?);
118 }
119 Some(s) => {
120 return Err(ParseError::LexerError(LexerError::UnknownEscapeSequence(
121 format!("\\{s}"),
122 )))
123 }
124 None => return Err(ParseError::LexerError(LexerError::UnterminatedString)),
125 },
126 ch => {
127 ret.push(ch);
128 }
129 }
130 }
131 Ok(ret.into())
132 } else {
133 Err(ParseError::unexpected_token(Token::Scalar(value)))
134 }
135 }
136}
137
138fn parse_unicode_codepoint<I>(char_iter: &mut I) -> Result<char, ParseError>
139where
140 I: Iterator<Item = char>,
141{
142 let escaped_code_point = char_iter
143 .next()
144 .ok_or_else(|| {
145 ParseError::LexerError(LexerError::UnknownEscapeSequence(String::from("\\u")))
146 })
147 .and_then(|c1| {
148 char_iter
149 .next()
150 .map(|c2| format!("{c1}{c2}"))
151 .ok_or_else(|| {
152 ParseError::LexerError(LexerError::UnknownEscapeSequence(format!("\\u{c1}")))
153 })
154 })
155 .and_then(|mut s| {
156 char_iter
157 .next()
158 .ok_or_else(|| {
159 ParseError::LexerError(LexerError::UnknownEscapeSequence(format!("\\u{s}")))
160 })
161 .map(|c2| {
162 s.push(c2);
163 s
164 })
165 })
166 .and_then(|mut s| {
167 char_iter
168 .next()
169 .ok_or_else(|| {
170 ParseError::LexerError(LexerError::UnknownEscapeSequence(format!("\\u{s}")))
171 })
172 .map(|c2| {
173 s.push(c2);
174 s
175 })
176 })?;
177 let code_point = u32::from_str_radix(&escaped_code_point, 16).map_err(|_| {
178 ParseError::LexerError(LexerError::UnknownEscapeSequence(format!(
179 "\\u{escaped_code_point}",
180 )))
181 })?;
182 char::from_u32(code_point).ok_or_else(|| {
183 ParseError::LexerError(LexerError::UnknownEscapeSequence(format!(
184 "\\u{escaped_code_point}",
185 )))
186 })
187}
188
189impl<S> reflect::WrappedType<S> for str {
190 const VALUE: reflect::WrappedValue = 1;
191}
192
193impl<S> reflect::BaseType<S> for str {
194 const NAME: reflect::Type = "String";
195}
196
197impl<S> reflect::BaseSubTypes<S> for str {
198 const NAMES: reflect::Types = &[<Self as reflect::BaseType<S>>::NAME];
199}
200
201impl<S> GraphQLType<S> for str
202where
203 S: ScalarValue,
204{
205 fn name(_: &()) -> Option<&'static str> {
206 Some("String")
207 }
208
209 fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S>
210 where
211 S: 'r,
212 {
213 registry.build_scalar_type::<String>(&()).into_meta()
214 }
215}
216
217impl<S> GraphQLValue<S> for str
218where
219 S: ScalarValue,
220{
221 type Context = ();
222 type TypeInfo = ();
223
224 fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> {
225 <Self as GraphQLType<S>>::name(info)
226 }
227
228 fn resolve(
229 &self,
230 _: &(),
231 _: Option<&[Selection<S>]>,
232 _: &Executor<Self::Context, S>,
233 ) -> ExecutionResult<S> {
234 Ok(Value::scalar(String::from(self)))
235 }
236}
237
238impl<S> GraphQLValueAsync<S> for str
239where
240 S: ScalarValue + Send + Sync,
241{
242 fn resolve_async<'a>(
243 &'a self,
244 info: &'a Self::TypeInfo,
245 selection_set: Option<&'a [Selection<S>]>,
246 executor: &'a Executor<Self::Context, S>,
247 ) -> crate::BoxFuture<'a, crate::ExecutionResult<S>> {
248 use futures::future;
249 Box::pin(future::ready(self.resolve(info, selection_set, executor)))
250 }
251}
252
253impl<'a, S> ToInputValue<S> for &'a str
254where
255 S: ScalarValue,
256{
257 fn to_input_value(&self) -> InputValue<S> {
258 InputValue::scalar(String::from(*self))
259 }
260}
261
262#[graphql_scalar(with = impl_boolean_scalar)]
263type Boolean = bool;
264
265mod impl_boolean_scalar {
266 use super::*;
267
268 pub(super) fn to_output<S: ScalarValue>(v: &Boolean) -> Value<S> {
269 Value::scalar(*v)
270 }
271
272 pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<Boolean, String> {
273 v.as_scalar_value()
274 .and_then(ScalarValue::as_bool)
275 .ok_or_else(|| format!("Expected `Boolean`, found: {v}"))
276 }
277
278 pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
279 Err(ParseError::unexpected_token(Token::Scalar(value)))
281 }
282}
283
284#[graphql_scalar(with = impl_int_scalar)]
285type Int = i32;
286
287mod impl_int_scalar {
288 use super::*;
289
290 pub(super) fn to_output<S: ScalarValue>(v: &Int) -> Value<S> {
291 Value::scalar(*v)
292 }
293
294 pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<Int, String> {
295 v.as_int_value()
296 .ok_or_else(|| format!("Expected `Int`, found: {v}"))
297 }
298
299 pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
300 if let ScalarToken::Int(v) = value {
301 v.parse()
302 .map_err(|_| ParseError::unexpected_token(Token::Scalar(value)))
303 .map(|s: i32| s.into())
304 } else {
305 Err(ParseError::unexpected_token(Token::Scalar(value)))
306 }
307 }
308}
309
310#[graphql_scalar(with = impl_float_scalar)]
311type Float = f64;
312
313mod impl_float_scalar {
314 use super::*;
315
316 pub(super) fn to_output<S: ScalarValue>(v: &Float) -> Value<S> {
317 Value::scalar(*v)
318 }
319
320 pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<Float, String> {
321 v.as_float_value()
322 .ok_or_else(|| format!("Expected `Float`, found: {v}"))
323 }
324
325 pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
326 match value {
327 ScalarToken::Int(v) => v
328 .parse()
329 .map_err(|_| ParseError::unexpected_token(Token::Scalar(value)))
330 .map(|s: i32| f64::from(s).into()),
331 ScalarToken::Float(v) => v
332 .parse()
333 .map_err(|_| ParseError::unexpected_token(Token::Scalar(value)))
334 .map(|s: f64| s.into()),
335 ScalarToken::String(_) => Err(ParseError::unexpected_token(Token::Scalar(value))),
336 }
337 }
338}
339
340#[derive(Debug)]
345pub struct EmptyMutation<T: ?Sized = ()>(PhantomData<JoinHandle<Box<T>>>);
346
347crate::sa::assert_impl_all!(EmptyMutation<Rc<String>>: Send, Sync);
349
350impl<T: ?Sized> EmptyMutation<T> {
351 #[inline]
353 pub fn new() -> Self {
354 Self(PhantomData)
355 }
356}
357
358impl<S, T> GraphQLType<S> for EmptyMutation<T>
359where
360 S: ScalarValue,
361{
362 fn name(_: &()) -> Option<&'static str> {
363 Some("_EmptyMutation")
364 }
365
366 fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S>
367 where
368 S: 'r,
369 {
370 registry.build_object_type::<Self>(&(), &[]).into_meta()
371 }
372}
373
374impl<S, T> GraphQLValue<S> for EmptyMutation<T>
375where
376 S: ScalarValue,
377{
378 type Context = T;
379 type TypeInfo = ();
380
381 fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> {
382 <Self as GraphQLType<S>>::name(info)
383 }
384}
385
386impl<S, T> GraphQLValueAsync<S> for EmptyMutation<T>
387where
388 Self::TypeInfo: Sync,
389 Self::Context: Sync,
390 S: ScalarValue + Send + Sync,
391{
392}
393
394impl<T> Default for EmptyMutation<T> {
397 fn default() -> Self {
398 Self::new()
399 }
400}
401
402pub struct EmptySubscription<T: ?Sized = ()>(PhantomData<JoinHandle<Box<T>>>);
407
408crate::sa::assert_impl_all!(EmptySubscription<Rc<String>>: Send, Sync);
410
411impl<T: ?Sized> EmptySubscription<T> {
412 #[inline]
414 pub fn new() -> Self {
415 Self(PhantomData)
416 }
417}
418
419impl<S, T> GraphQLType<S> for EmptySubscription<T>
420where
421 S: ScalarValue,
422{
423 fn name(_: &()) -> Option<&'static str> {
424 Some("_EmptySubscription")
425 }
426
427 fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S>
428 where
429 S: 'r,
430 {
431 registry.build_object_type::<Self>(&(), &[]).into_meta()
432 }
433}
434
435impl<S, T> GraphQLValue<S> for EmptySubscription<T>
436where
437 S: ScalarValue,
438{
439 type Context = T;
440 type TypeInfo = ();
441
442 fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> {
443 <Self as GraphQLType<S>>::name(info)
444 }
445}
446
447impl<T, S> GraphQLSubscriptionValue<S> for EmptySubscription<T>
448where
449 Self::TypeInfo: Sync,
450 Self::Context: Sync,
451 S: ScalarValue + Send + Sync + 'static,
452{
453}
454
455impl<T> Default for EmptySubscription<T> {
458 fn default() -> Self {
459 Self::new()
460 }
461}
462
463#[cfg(test)]
464mod tests {
465 use crate::{
466 parser::ScalarToken,
467 value::{DefaultScalarValue, ParseScalarValue},
468 };
469
470 use super::{EmptyMutation, EmptySubscription, ID};
471
472 #[test]
473 fn test_id_from_string() {
474 let actual = ID::from(String::from("foo"));
475 let expected = ID(String::from("foo"));
476 assert_eq!(actual, expected);
477 }
478
479 #[test]
480 fn test_id_new() {
481 let actual = ID::new("foo");
482 let expected = ID(String::from("foo"));
483 assert_eq!(actual, expected);
484 }
485
486 #[test]
487 fn test_id_deref() {
488 let id = ID(String::from("foo"));
489 assert_eq!(id.len(), 3);
490 }
491
492 #[test]
493 fn test_id_display() {
494 let id = ID("foo".into());
495 assert_eq!(id.to_string(), "foo");
496 }
497
498 #[test]
499 fn parse_strings() {
500 fn parse_string(s: &str, expected: &str) {
501 let s =
502 <String as ParseScalarValue<DefaultScalarValue>>::from_str(ScalarToken::String(s));
503 assert!(s.is_ok(), "A parsing error occurred: {s:?}");
504 let s: Option<String> = s.unwrap().into();
505 assert!(s.is_some(), "No string returned");
506 assert_eq!(s.unwrap(), expected);
507 }
508
509 parse_string("simple", "simple");
510 parse_string(" white space ", " white space ");
511 parse_string(r#"quote \""#, "quote \"");
512 parse_string(r"escaped \n\r\b\t\f", "escaped \n\r\u{0008}\t\u{000c}");
513 parse_string(r"slashes \\ \/", "slashes \\ /");
514 parse_string(
515 r"unicode \u1234\u5678\u90AB\uCDEF",
516 "unicode \u{1234}\u{5678}\u{90ab}\u{cdef}",
517 );
518 }
519
520 #[test]
521 fn parse_f64_from_int() {
522 for (v, expected) in [
523 ("0", 0),
524 ("128", 128),
525 ("1601942400", 1601942400),
526 ("1696550400", 1696550400),
527 ("-1", -1),
528 ] {
529 let n = <f64 as ParseScalarValue<DefaultScalarValue>>::from_str(ScalarToken::Int(v));
530 assert!(n.is_ok(), "A parsing error occurred: {:?}", n.unwrap_err());
531
532 let n: Option<f64> = n.unwrap().into();
533 assert!(n.is_some(), "No `f64` returned");
534 assert_eq!(n.unwrap(), f64::from(expected));
535 }
536 }
537
538 #[test]
539 fn parse_f64_from_float() {
540 for (v, expected) in [
541 ("0.", 0.),
542 ("1.2", 1.2),
543 ("1601942400.", 1601942400.),
544 ("1696550400.", 1696550400.),
545 ("-1.2", -1.2),
546 ] {
547 let n = <f64 as ParseScalarValue<DefaultScalarValue>>::from_str(ScalarToken::Float(v));
548 assert!(n.is_ok(), "A parsing error occurred: {:?}", n.unwrap_err());
549
550 let n: Option<f64> = n.unwrap().into();
551 assert!(n.is_some(), "No `f64` returned");
552 assert_eq!(n.unwrap(), expected);
553 }
554 }
555
556 #[test]
557 fn empty_mutation_is_send() {
558 fn check_if_send<T: Send>() {}
559 check_if_send::<EmptyMutation<()>>();
560 }
561
562 #[test]
563 fn empty_subscription_is_send() {
564 fn check_if_send<T: Send>() {}
565 check_if_send::<EmptySubscription<()>>();
566 }
567
568 #[test]
569 fn default_is_invariant_over_type() {
570 struct Bar;
571 let _ = EmptySubscription::<Bar>::default();
572 let _ = EmptyMutation::<Bar>::default();
573 }
574}