1use std::{
4 borrow::Cow,
5 cmp::Ordering,
6 collections::HashMap,
7 fmt::{Debug, Display},
8 sync::{Arc, RwLock},
9};
10
11use fnv::FnvHashMap;
12use futures::Stream;
13
14use crate::{
15 ast::{
16 Definition, Document, Fragment, FromInputValue, InputValue, Operation, OperationType,
17 Selection, ToInputValue, Type,
18 },
19 parser::{SourcePosition, Spanning},
20 schema::{
21 meta::{
22 Argument, DeprecationStatus, EnumMeta, EnumValue, Field, InputObjectMeta,
23 InterfaceMeta, ListMeta, MetaType, NullableMeta, ObjectMeta, PlaceholderMeta,
24 ScalarMeta, UnionMeta,
25 },
26 model::{RootNode, SchemaType, TypeType},
27 },
28 types::{
29 async_await::{GraphQLTypeAsync, GraphQLValueAsync},
30 base::{GraphQLType, GraphQLValue},
31 name::Name,
32 subscriptions::{GraphQLSubscriptionType, GraphQLSubscriptionValue},
33 },
34 value::{DefaultScalarValue, ParseScalarValue, ScalarValue, Value},
35 GraphQLError,
36};
37
38pub use self::{
39 look_ahead::{
40 Applies, LookAheadArgument, LookAheadChildren, LookAheadList, LookAheadObject,
41 LookAheadSelection, LookAheadValue,
42 },
43 owned_executor::OwnedExecutor,
44};
45
46mod look_ahead;
47mod owned_executor;
48
49pub struct Registry<'r, S = DefaultScalarValue> {
55 pub types: FnvHashMap<Name, MetaType<'r, S>>,
57}
58
59#[allow(missing_docs)]
60#[derive(Clone)]
61pub enum FieldPath<'a> {
62 Root(SourcePosition),
63 Field(&'a str, SourcePosition, Arc<FieldPath<'a>>),
64}
65
66pub struct Executor<'r, 'a, CtxT, S = DefaultScalarValue>
71where
72 CtxT: 'a,
73 S: 'a,
74{
75 fragments: &'r HashMap<&'a str, Fragment<'a, S>>,
76 variables: &'r Variables<S>,
77 current_selection_set: Option<&'r [Selection<'a, S>]>,
78 parent_selection_set: Option<&'r [Selection<'a, S>]>,
79 current_type: TypeType<'a, S>,
80 schema: &'a SchemaType<'a, S>,
81 context: &'a CtxT,
82 errors: &'r RwLock<Vec<ExecutionError<S>>>,
83 field_path: Arc<FieldPath<'a>>,
84}
85
86#[derive(Clone, Debug, PartialEq)]
91pub struct ExecutionError<S> {
92 location: SourcePosition,
93 path: Vec<String>,
94 error: FieldError<S>,
95}
96
97impl<S> Eq for ExecutionError<S> where Self: PartialEq {}
98
99impl<S> ExecutionError<S> {
100 pub fn at_origin(error: FieldError<S>) -> ExecutionError<S> {
102 ExecutionError {
103 location: SourcePosition::new_origin(),
104 path: Vec::new(),
105 error,
106 }
107 }
108}
109
110impl<S> PartialOrd for ExecutionError<S>
111where
112 Self: PartialEq,
113{
114 fn partial_cmp(&self, other: &ExecutionError<S>) -> Option<Ordering> {
115 Some(self.cmp(other))
116 }
117}
118
119impl<S> Ord for ExecutionError<S>
120where
121 Self: Eq,
122{
123 fn cmp(&self, other: &ExecutionError<S>) -> Ordering {
124 (&self.location, &self.path, &self.error.message).cmp(&(
125 &other.location,
126 &other.path,
127 &other.error.message,
128 ))
129 }
130}
131
132#[derive(Clone, Debug, PartialEq)]
149pub struct FieldError<S = DefaultScalarValue> {
150 message: String,
151 extensions: Value<S>,
152}
153
154impl<T: Display, S> From<T> for FieldError<S> {
155 fn from(e: T) -> Self {
156 Self {
157 message: e.to_string(),
158 extensions: Value::Null,
159 }
160 }
161}
162
163impl<S> FieldError<S> {
164 #[must_use]
195 pub fn new<T: Display>(e: T, extensions: Value<S>) -> Self {
196 Self {
197 message: e.to_string(),
198 extensions,
199 }
200 }
201
202 #[must_use]
204 pub fn message(&self) -> &str {
205 &self.message
206 }
207
208 #[must_use]
212 pub fn extensions(&self) -> &Value<S> {
213 &self.extensions
214 }
215
216 #[must_use]
219 pub fn map_scalar_value<Into>(self) -> FieldError<Into>
220 where
221 S: ScalarValue,
222 Into: ScalarValue,
223 {
224 FieldError {
225 message: self.message,
226 extensions: self.extensions.map_scalar_value(),
227 }
228 }
229
230 #[must_use]
232 pub fn map_message(self, f: impl FnOnce(String) -> String) -> Self {
233 Self {
234 message: f(self.message),
235 extensions: self.extensions,
236 }
237 }
238}
239
240pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>;
242
243pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>;
245
246pub type ValuesStream<'a, S = DefaultScalarValue> =
248 std::pin::Pin<Box<dyn Stream<Item = Result<Value<S>, ExecutionError<S>>> + Send + 'a>>;
249
250pub type Variables<S = DefaultScalarValue> = HashMap<String, InputValue<S>>;
252
253pub trait IntoFieldError<S = DefaultScalarValue> {
259 #[must_use]
261 fn into_field_error(self) -> FieldError<S>;
262}
263
264impl<S1: ScalarValue, S2: ScalarValue> IntoFieldError<S2> for FieldError<S1> {
265 fn into_field_error(self) -> FieldError<S2> {
266 self.map_scalar_value()
267 }
268}
269
270impl<S> IntoFieldError<S> for std::convert::Infallible {
271 fn into_field_error(self) -> FieldError<S> {
272 match self {}
273 }
274}
275
276impl<'a, S> IntoFieldError<S> for &'a str {
277 fn into_field_error(self) -> FieldError<S> {
278 FieldError::<S>::from(self)
279 }
280}
281
282impl<S> IntoFieldError<S> for String {
283 fn into_field_error(self) -> FieldError<S> {
284 FieldError::<S>::from(self)
285 }
286}
287
288impl<'a, S> IntoFieldError<S> for Cow<'a, str> {
289 fn into_field_error(self) -> FieldError<S> {
290 FieldError::<S>::from(self)
291 }
292}
293
294#[doc(hidden)]
295pub trait IntoResolvable<'a, S, T, C>
296where
297 T: GraphQLValue<S>,
298 S: ScalarValue,
299{
300 type Type;
301
302 #[doc(hidden)]
303 fn into_resolvable(self, ctx: &'a C) -> FieldResult<Option<(&'a T::Context, T)>, S>;
304}
305
306impl<'a, S, T, C> IntoResolvable<'a, S, T, C> for T
307where
308 T: GraphQLValue<S>,
309 S: ScalarValue,
310 T::Context: FromContext<C>,
311{
312 type Type = T;
313
314 fn into_resolvable(self, ctx: &'a C) -> FieldResult<Option<(&'a T::Context, T)>, S> {
315 Ok(Some((FromContext::from(ctx), self)))
316 }
317}
318
319impl<'a, S, T, C, E: IntoFieldError<S>> IntoResolvable<'a, S, T, C> for Result<T, E>
320where
321 S: ScalarValue,
322 T: GraphQLValue<S>,
323 T::Context: FromContext<C>,
324{
325 type Type = T;
326
327 fn into_resolvable(self, ctx: &'a C) -> FieldResult<Option<(&'a T::Context, T)>, S> {
328 self.map(|v: T| Some((<T::Context as FromContext<C>>::from(ctx), v)))
329 .map_err(IntoFieldError::into_field_error)
330 }
331}
332
333impl<'a, S, T, C> IntoResolvable<'a, S, T, C> for (&'a T::Context, T)
334where
335 S: ScalarValue,
336 T: GraphQLValue<S>,
337{
338 type Type = T;
339
340 fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, T)>, S> {
341 Ok(Some(self))
342 }
343}
344
345impl<'a, S, T, C> IntoResolvable<'a, S, Option<T>, C> for Option<(&'a T::Context, T)>
346where
347 S: ScalarValue,
348 T: GraphQLValue<S>,
349{
350 type Type = T;
351
352 #[allow(clippy::type_complexity)]
353 fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>, S> {
354 Ok(self.map(|(ctx, v)| (ctx, Some(v))))
355 }
356}
357
358impl<'a, S1, S2, T, C> IntoResolvable<'a, S2, T, C> for FieldResult<(&'a T::Context, T), S1>
359where
360 S1: ScalarValue,
361 S2: ScalarValue,
362 T: GraphQLValue<S2>,
363{
364 type Type = T;
365
366 fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, T)>, S2> {
367 self.map(Some).map_err(FieldError::map_scalar_value)
368 }
369}
370
371impl<'a, S1, S2, T, C> IntoResolvable<'a, S2, Option<T>, C>
372 for FieldResult<Option<(&'a T::Context, T)>, S1>
373where
374 S1: ScalarValue,
375 S2: ScalarValue,
376 T: GraphQLValue<S2>,
377{
378 type Type = T;
379
380 #[allow(clippy::type_complexity)]
381 fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>, S2> {
382 self.map(|o| o.map(|(ctx, v)| (ctx, Some(v))))
383 .map_err(FieldError::map_scalar_value)
384 }
385}
386
387pub trait FromContext<T> {
399 fn from(value: &T) -> &Self;
401}
402
403pub trait Context {}
405
406impl<'a, C: Context> Context for &'a C {}
407
408static NULL_CONTEXT: () = ();
409
410impl<T> FromContext<T> for () {
411 fn from(_: &T) -> &Self {
412 &NULL_CONTEXT
413 }
414}
415
416impl<T> FromContext<T> for T
417where
418 T: Context,
419{
420 fn from(value: &T) -> &Self {
421 value
422 }
423}
424
425impl<'r, 'a, CtxT, S> Executor<'r, 'a, CtxT, S>
426where
427 S: ScalarValue,
428{
429 pub async fn resolve_into_stream<'i, 'v, 'res, T>(
433 &'r self,
434 info: &'i T::TypeInfo,
435 value: &'v T,
436 ) -> Value<ValuesStream<'res, S>>
437 where
438 'i: 'res,
439 'v: 'res,
440 'a: 'res,
441 T: GraphQLSubscriptionValue<S, Context = CtxT> + ?Sized,
442 T::TypeInfo: Sync,
443 CtxT: Sync,
444 S: Send + Sync,
445 {
446 self.subscribe(info, value).await.unwrap_or_else(|e| {
447 self.push_error(e);
448 Value::Null
449 })
450 }
451
452 pub async fn subscribe<'s, 't, 'res, T>(
455 &'r self,
456 info: &'t T::TypeInfo,
457 value: &'t T,
458 ) -> Result<Value<ValuesStream<'res, S>>, FieldError<S>>
459 where
460 't: 'res,
461 'a: 'res,
462 T: GraphQLSubscriptionValue<S, Context = CtxT> + ?Sized,
463 T::TypeInfo: Sync,
464 CtxT: Sync,
465 S: Send + Sync,
466 {
467 value.resolve_into_stream(info, self).await
468 }
469
470 pub fn resolve_with_ctx<NewCtxT, T>(&self, info: &T::TypeInfo, value: &T) -> ExecutionResult<S>
472 where
473 NewCtxT: FromContext<CtxT>,
474 T: GraphQLValue<S, Context = NewCtxT> + ?Sized,
475 {
476 self.replaced_context(<NewCtxT as FromContext<CtxT>>::from(self.context))
477 .resolve(info, value)
478 }
479
480 pub fn resolve<T>(&self, info: &T::TypeInfo, value: &T) -> ExecutionResult<S>
482 where
483 T: GraphQLValue<S, Context = CtxT> + ?Sized,
484 {
485 value.resolve(info, self.current_selection_set, self)
486 }
487
488 pub async fn resolve_async<T>(&self, info: &T::TypeInfo, value: &T) -> ExecutionResult<S>
490 where
491 T: GraphQLValueAsync<S, Context = CtxT> + ?Sized,
492 T::TypeInfo: Sync,
493 CtxT: Sync,
494 S: Send + Sync,
495 {
496 value
497 .resolve_async(info, self.current_selection_set, self)
498 .await
499 }
500
501 pub async fn resolve_with_ctx_async<NewCtxT, T>(
503 &self,
504 info: &T::TypeInfo,
505 value: &T,
506 ) -> ExecutionResult<S>
507 where
508 T: GraphQLValueAsync<S, Context = NewCtxT> + ?Sized,
509 T::TypeInfo: Sync,
510 NewCtxT: FromContext<CtxT> + Sync,
511 S: Send + Sync,
512 {
513 let e = self.replaced_context(<NewCtxT as FromContext<CtxT>>::from(self.context));
514 e.resolve_async(info, value).await
515 }
516
517 pub fn resolve_into_value<T>(&self, info: &T::TypeInfo, value: &T) -> Value<S>
521 where
522 T: GraphQLValue<S, Context = CtxT>,
523 {
524 self.resolve(info, value).unwrap_or_else(|e| {
525 self.push_error(e);
526 Value::null()
527 })
528 }
529
530 pub async fn resolve_into_value_async<T>(&self, info: &T::TypeInfo, value: &T) -> Value<S>
534 where
535 T: GraphQLValueAsync<S, Context = CtxT> + ?Sized,
536 T::TypeInfo: Sync,
537 CtxT: Sync,
538 S: Send + Sync,
539 {
540 self.resolve_async(info, value).await.unwrap_or_else(|e| {
541 self.push_error(e);
542 Value::null()
543 })
544 }
545
546 pub fn replaced_context<'b, NewCtxT>(
551 &'b self,
552 ctx: &'b NewCtxT,
553 ) -> Executor<'b, 'b, NewCtxT, S> {
554 Executor {
555 fragments: self.fragments,
556 variables: self.variables,
557 current_selection_set: self.current_selection_set,
558 parent_selection_set: self.parent_selection_set,
559 current_type: self.current_type.clone(),
560 schema: self.schema,
561 context: ctx,
562 errors: self.errors,
563 field_path: self.field_path.clone(),
564 }
565 }
566
567 #[doc(hidden)]
568 pub fn field_sub_executor<'s>(
569 &'s self,
570 field_alias: &'a str,
571 field_name: &'s str,
572 location: SourcePosition,
573 selection_set: Option<&'s [Selection<'a, S>]>,
574 ) -> Executor<'s, 'a, CtxT, S> {
575 Executor {
576 fragments: self.fragments,
577 variables: self.variables,
578 current_selection_set: selection_set,
579 parent_selection_set: self.current_selection_set,
580 current_type: self.schema.make_type(
581 &self
582 .current_type
583 .innermost_concrete()
584 .field_by_name(field_name)
585 .expect("Field not found on inner type")
586 .field_type,
587 ),
588 schema: self.schema,
589 context: self.context,
590 errors: self.errors,
591 field_path: Arc::new(FieldPath::Field(
592 field_alias,
593 location,
594 Arc::clone(&self.field_path),
595 )),
596 }
597 }
598
599 #[doc(hidden)]
600 pub fn type_sub_executor<'s>(
601 &'s self,
602 type_name: Option<&'s str>,
603 selection_set: Option<&'s [Selection<'a, S>]>,
604 ) -> Executor<'s, 'a, CtxT, S> {
605 Executor {
606 fragments: self.fragments,
607 variables: self.variables,
608 current_selection_set: selection_set,
609 parent_selection_set: self.current_selection_set,
610 current_type: match type_name {
611 Some(type_name) => self.schema.type_by_name(type_name).expect("Type not found"),
612 None => self.current_type.clone(),
613 },
614 schema: self.schema,
615 context: self.context,
616 errors: self.errors,
617 field_path: self.field_path.clone(),
618 }
619 }
620
621 pub(crate) fn current_selection_set(&self) -> Option<&[Selection<'a, S>]> {
623 self.current_selection_set
624 }
625
626 pub fn context(&self) -> &'r CtxT {
631 self.context
632 }
633
634 pub fn schema(&self) -> &'a SchemaType<S> {
636 self.schema
637 }
638
639 #[doc(hidden)]
640 pub fn current_type(&self) -> &TypeType<'a, S> {
641 &self.current_type
642 }
643
644 #[doc(hidden)]
645 pub fn variables(&self) -> &'r Variables<S> {
646 self.variables
647 }
648
649 #[doc(hidden)]
650 pub fn fragment_by_name<'s>(&'s self, name: &str) -> Option<&'s Fragment<'a, S>> {
651 self.fragments.get(name)
652 }
653
654 pub fn location(&self) -> &SourcePosition {
656 self.field_path.location()
657 }
658
659 pub fn push_error(&self, error: FieldError<S>) {
661 self.push_error_at(error, *self.location());
662 }
663
664 pub fn push_error_at(&self, error: FieldError<S>, location: SourcePosition) {
666 let mut path = Vec::new();
667 self.field_path.construct_path(&mut path);
668
669 let mut errors = self.errors.write().unwrap();
670
671 errors.push(ExecutionError {
672 location,
673 path,
674 error,
675 });
676 }
677
678 pub fn new_error(&self, error: FieldError<S>) -> ExecutionError<S> {
680 let mut path = Vec::new();
681 self.field_path.construct_path(&mut path);
682
683 ExecutionError {
684 location: *self.location(),
685 path,
686 error,
687 }
688 }
689
690 pub fn look_ahead(&'a self) -> LookAheadSelection<'a, S> {
695 let field_name = match *self.field_path {
696 FieldPath::Field(x, ..) => x,
697 FieldPath::Root(_) => unreachable!(),
698 };
699 self.parent_selection_set
700 .and_then(|p| {
701 p.iter().find_map(|x| {
703 match x {
704 Selection::Field(ref field) => {
705 let field = &field.item;
706 let name = field.name.item;
708 let alias = field.alias.as_ref().map(|a| a.item);
709
710 (alias.unwrap_or(name) == field_name).then(|| {
711 LookAheadSelection::new(
712 look_ahead::SelectionSource::Field(field),
713 self.variables,
714 self.fragments,
715 )
716 })
717 }
718 Selection::FragmentSpread(_) | Selection::InlineFragment(_) => None,
719 }
720 })
721 })
722 .unwrap_or_else(|| {
723 LookAheadSelection::new(
726 look_ahead::SelectionSource::Spread {
727 field_name,
728 set: self.current_selection_set,
729 },
730 self.variables,
731 self.fragments,
732 )
733 })
734 }
735
736 pub fn as_owned_executor(&self) -> OwnedExecutor<'a, CtxT, S> {
744 OwnedExecutor {
745 fragments: self.fragments.clone(),
746 variables: self.variables.clone(),
747 current_selection_set: self.current_selection_set.map(|x| x.to_vec()),
748 parent_selection_set: self.parent_selection_set.map(|x| x.to_vec()),
749 current_type: self.current_type.clone(),
750 schema: self.schema,
751 context: self.context,
752 errors: RwLock::new(vec![]),
753 field_path: Arc::clone(&self.field_path),
754 }
755 }
756}
757
758impl<'a> FieldPath<'a> {
759 fn construct_path(&self, acc: &mut Vec<String>) {
760 match self {
761 FieldPath::Root(_) => (),
762 FieldPath::Field(name, _, parent) => {
763 parent.construct_path(acc);
764 acc.push((*name).into());
765 }
766 }
767 }
768
769 fn location(&self) -> &SourcePosition {
770 match *self {
771 FieldPath::Root(ref pos) | FieldPath::Field(_, ref pos, _) => pos,
772 }
773 }
774}
775
776impl<S> ExecutionError<S> {
777 #[doc(hidden)]
778 pub fn new(location: SourcePosition, path: &[&str], error: FieldError<S>) -> ExecutionError<S> {
779 ExecutionError {
780 location,
781 path: path.iter().map(|s| (*s).into()).collect(),
782 error,
783 }
784 }
785
786 pub fn error(&self) -> &FieldError<S> {
788 &self.error
789 }
790
791 pub fn location(&self) -> &SourcePosition {
793 &self.location
794 }
795
796 pub fn path(&self) -> &[String] {
798 &self.path
799 }
800}
801
802pub fn execute_validated_query<'b, QueryT, MutationT, SubscriptionT, S>(
805 document: &'b Document<S>,
806 operation: &'b Spanning<Operation<S>>,
807 root_node: &RootNode<QueryT, MutationT, SubscriptionT, S>,
808 variables: &Variables<S>,
809 context: &QueryT::Context,
810) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
811where
812 S: ScalarValue,
813 QueryT: GraphQLType<S>,
814 MutationT: GraphQLType<S, Context = QueryT::Context>,
815 SubscriptionT: GraphQLType<S, Context = QueryT::Context>,
816{
817 if operation.item.operation_type == OperationType::Subscription {
818 return Err(GraphQLError::IsSubscription);
819 }
820
821 let mut fragments = vec![];
822 for def in document.iter() {
823 if let Definition::Fragment(f) = def {
824 fragments.push(f)
825 };
826 }
827
828 let default_variable_values = operation.item.variable_definitions.as_ref().map(|defs| {
829 defs.item
830 .items
831 .iter()
832 .filter_map(|(name, def)| {
833 def.default_value
834 .as_ref()
835 .map(|i| (name.item.into(), i.item.clone()))
836 })
837 .collect::<HashMap<String, InputValue<S>>>()
838 });
839
840 let errors = RwLock::new(Vec::new());
841 let value;
842
843 {
844 let mut all_vars;
845 let mut final_vars = variables;
846
847 if let Some(defaults) = default_variable_values {
848 all_vars = variables.clone();
849
850 for (name, value) in defaults {
851 all_vars.entry(name).or_insert(value);
852 }
853
854 final_vars = &all_vars;
855 }
856
857 let root_type = match operation.item.operation_type {
858 OperationType::Query => root_node.schema.query_type(),
859 OperationType::Mutation => root_node
860 .schema
861 .mutation_type()
862 .expect("No mutation type found"),
863 OperationType::Subscription => unreachable!(),
864 };
865
866 let executor = Executor {
867 fragments: &fragments
868 .iter()
869 .map(|f| (f.item.name.item, f.item.clone()))
870 .collect(),
871 variables: final_vars,
872 current_selection_set: Some(&operation.item.selection_set[..]),
873 parent_selection_set: None,
874 current_type: root_type,
875 schema: &root_node.schema,
876 context,
877 errors: &errors,
878 field_path: Arc::new(FieldPath::Root(operation.span.start)),
879 };
880
881 value = match operation.item.operation_type {
882 OperationType::Query => executor.resolve_into_value(&root_node.query_info, &root_node),
883 OperationType::Mutation => {
884 executor.resolve_into_value(&root_node.mutation_info, &root_node.mutation_type)
885 }
886 OperationType::Subscription => unreachable!(),
887 };
888 }
889
890 let mut errors = errors.into_inner().unwrap();
891 errors.sort();
892
893 Ok((value, errors))
894}
895
896pub async fn execute_validated_query_async<'a, 'b, QueryT, MutationT, SubscriptionT, S>(
899 document: &'b Document<'a, S>,
900 operation: &'b Spanning<Operation<'_, S>>,
901 root_node: &RootNode<'a, QueryT, MutationT, SubscriptionT, S>,
902 variables: &Variables<S>,
903 context: &QueryT::Context,
904) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
905where
906 QueryT: GraphQLTypeAsync<S>,
907 QueryT::TypeInfo: Sync,
908 QueryT::Context: Sync,
909 MutationT: GraphQLTypeAsync<S, Context = QueryT::Context>,
910 MutationT::TypeInfo: Sync,
911 SubscriptionT: GraphQLType<S, Context = QueryT::Context> + Sync,
912 SubscriptionT::TypeInfo: Sync,
913 S: ScalarValue + Send + Sync,
914{
915 if operation.item.operation_type == OperationType::Subscription {
916 return Err(GraphQLError::IsSubscription);
917 }
918
919 let mut fragments = vec![];
920 for def in document.iter() {
921 if let Definition::Fragment(f) = def {
922 fragments.push(f)
923 };
924 }
925
926 let default_variable_values = operation.item.variable_definitions.as_ref().map(|defs| {
927 defs.item
928 .items
929 .iter()
930 .filter_map(|(name, def)| {
931 def.default_value
932 .as_ref()
933 .map(|i| (name.item.into(), i.item.clone()))
934 })
935 .collect::<HashMap<String, InputValue<S>>>()
936 });
937
938 let errors = RwLock::new(Vec::new());
939 let value;
940
941 {
942 let mut all_vars;
943 let mut final_vars = variables;
944
945 if let Some(defaults) = default_variable_values {
946 all_vars = variables.clone();
947
948 for (name, value) in defaults {
949 all_vars.entry(name).or_insert(value);
950 }
951
952 final_vars = &all_vars;
953 }
954
955 let root_type = match operation.item.operation_type {
956 OperationType::Query => root_node.schema.query_type(),
957 OperationType::Mutation => root_node
958 .schema
959 .mutation_type()
960 .expect("No mutation type found"),
961 OperationType::Subscription => unreachable!(),
962 };
963
964 let executor = Executor {
965 fragments: &fragments
966 .iter()
967 .map(|f| (f.item.name.item, f.item.clone()))
968 .collect(),
969 variables: final_vars,
970 current_selection_set: Some(&operation.item.selection_set[..]),
971 parent_selection_set: None,
972 current_type: root_type,
973 schema: &root_node.schema,
974 context,
975 errors: &errors,
976 field_path: Arc::new(FieldPath::Root(operation.span.start)),
977 };
978
979 value = match operation.item.operation_type {
980 OperationType::Query => {
981 executor
982 .resolve_into_value_async(&root_node.query_info, &root_node)
983 .await
984 }
985 OperationType::Mutation => {
986 executor
987 .resolve_into_value_async(&root_node.mutation_info, &root_node.mutation_type)
988 .await
989 }
990 OperationType::Subscription => unreachable!(),
991 };
992 }
993
994 let mut errors = errors.into_inner().unwrap();
995 errors.sort();
996
997 Ok((value, errors))
998}
999
1000#[doc(hidden)]
1001pub fn get_operation<'b, 'd, S>(
1002 document: &'b Document<'d, S>,
1003 operation_name: Option<&str>,
1004) -> Result<&'b Spanning<Operation<'d, S>>, GraphQLError>
1005where
1006 S: ScalarValue,
1007{
1008 let mut operation = None;
1009 for def in document {
1010 if let Definition::Operation(op) = def {
1011 if operation_name.is_none() && operation.is_some() {
1012 return Err(GraphQLError::MultipleOperationsProvided);
1013 }
1014
1015 let move_op =
1016 operation_name.is_none() || op.item.name.as_ref().map(|s| s.item) == operation_name;
1017
1018 if move_op {
1019 operation = Some(op);
1020 }
1021 };
1022 }
1023 let op = match operation {
1024 Some(op) => op,
1025 None => return Err(GraphQLError::UnknownOperationName),
1026 };
1027 Ok(op)
1028}
1029
1030pub async fn resolve_validated_subscription<
1034 'r,
1035 'exec_ref,
1036 'd,
1037 'op,
1038 QueryT,
1039 MutationT,
1040 SubscriptionT,
1041 S,
1042>(
1043 document: &Document<'d, S>,
1044 operation: &Spanning<Operation<'op, S>>,
1045 root_node: &'r RootNode<'r, QueryT, MutationT, SubscriptionT, S>,
1046 variables: &Variables<S>,
1047 context: &'r QueryT::Context,
1048) -> Result<(Value<ValuesStream<'r, S>>, Vec<ExecutionError<S>>), GraphQLError>
1049where
1050 'r: 'exec_ref,
1051 'd: 'r,
1052 'op: 'd,
1053 QueryT: GraphQLTypeAsync<S>,
1054 QueryT::TypeInfo: Sync,
1055 QueryT::Context: Sync + 'r,
1056 MutationT: GraphQLTypeAsync<S, Context = QueryT::Context>,
1057 MutationT::TypeInfo: Sync,
1058 SubscriptionT: GraphQLSubscriptionType<S, Context = QueryT::Context>,
1059 SubscriptionT::TypeInfo: Sync,
1060 S: ScalarValue + Send + Sync,
1061{
1062 if operation.item.operation_type != OperationType::Subscription {
1063 return Err(GraphQLError::NotSubscription);
1064 }
1065
1066 let mut fragments = vec![];
1067 for def in document.iter() {
1068 if let Definition::Fragment(f) = def {
1069 fragments.push(f)
1070 }
1071 }
1072
1073 let default_variable_values = operation.item.variable_definitions.as_ref().map(|defs| {
1074 defs.item
1075 .items
1076 .iter()
1077 .filter_map(|(name, def)| {
1078 def.default_value
1079 .as_ref()
1080 .map(|i| (name.item.into(), i.item.clone()))
1081 })
1082 .collect::<HashMap<String, InputValue<S>>>()
1083 });
1084
1085 let errors = RwLock::new(Vec::new());
1086 let value;
1087
1088 {
1089 let mut all_vars;
1090 let mut final_vars = variables;
1091
1092 if let Some(defaults) = default_variable_values {
1093 all_vars = variables.clone();
1094
1095 for (name, value) in defaults {
1096 all_vars.entry(name).or_insert(value);
1097 }
1098
1099 final_vars = &all_vars;
1100 }
1101
1102 let root_type = match operation.item.operation_type {
1103 OperationType::Subscription => root_node
1104 .schema
1105 .subscription_type()
1106 .expect("No subscription type found"),
1107 _ => unreachable!(),
1108 };
1109
1110 let executor: Executor<'_, 'r, _, _> = Executor {
1111 fragments: &fragments
1112 .iter()
1113 .map(|f| (f.item.name.item, f.item.clone()))
1114 .collect(),
1115 variables: final_vars,
1116 current_selection_set: Some(&operation.item.selection_set[..]),
1117 parent_selection_set: None,
1118 current_type: root_type,
1119 schema: &root_node.schema,
1120 context,
1121 errors: &errors,
1122 field_path: Arc::new(FieldPath::Root(operation.span.start)),
1123 };
1124
1125 value = match operation.item.operation_type {
1126 OperationType::Subscription => {
1127 executor
1128 .resolve_into_stream(&root_node.subscription_info, &root_node.subscription_type)
1129 .await
1130 }
1131 _ => unreachable!(),
1132 };
1133 }
1134
1135 let mut errors = errors.into_inner().unwrap();
1136 errors.sort();
1137
1138 Ok((value, errors))
1139}
1140
1141impl<'r, S: 'r> Registry<'r, S> {
1142 pub fn new(types: FnvHashMap<Name, MetaType<'r, S>>) -> Self {
1144 Self { types }
1145 }
1146
1147 pub fn get_type<T>(&mut self, info: &T::TypeInfo) -> Type<'r>
1153 where
1154 T: GraphQLType<S> + ?Sized,
1155 S: ScalarValue,
1156 {
1157 if let Some(name) = T::name(info) {
1158 let validated_name = name.parse::<Name>().unwrap();
1159 if !self.types.contains_key(name) {
1160 self.insert_placeholder(
1161 validated_name.clone(),
1162 Type::NonNullNamed(Cow::Owned(name.into())),
1163 );
1164 let meta = T::meta(info, self);
1165 self.types.insert(validated_name, meta);
1166 }
1167 self.types[name].as_type()
1168 } else {
1169 T::meta(info, self).as_type()
1170 }
1171 }
1172
1173 pub fn field<T>(&mut self, name: &str, info: &T::TypeInfo) -> Field<'r, S>
1175 where
1176 T: GraphQLType<S> + ?Sized,
1177 S: ScalarValue,
1178 {
1179 Field {
1180 name: smartstring::SmartString::from(name),
1181 description: None,
1182 arguments: None,
1183 field_type: self.get_type::<T>(info),
1184 deprecation_status: DeprecationStatus::Current,
1185 }
1186 }
1187
1188 #[doc(hidden)]
1189 pub fn field_convert<'a, T: IntoResolvable<'a, S, I, C>, I, C>(
1190 &mut self,
1191 name: &str,
1192 info: &I::TypeInfo,
1193 ) -> Field<'r, S>
1194 where
1195 I: GraphQLType<S>,
1196 S: ScalarValue,
1197 {
1198 Field {
1199 name: name.into(),
1200 description: None,
1201 arguments: None,
1202 field_type: self.get_type::<I>(info),
1203 deprecation_status: DeprecationStatus::Current,
1204 }
1205 }
1206
1207 pub fn arg<T>(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S>
1209 where
1210 T: GraphQLType<S> + FromInputValue<S>,
1211 S: ScalarValue,
1212 {
1213 Argument::new(name, self.get_type::<T>(info))
1214 }
1215
1216 pub fn arg_with_default<T>(
1218 &mut self,
1219 name: &str,
1220 value: &T,
1221 info: &T::TypeInfo,
1222 ) -> Argument<'r, S>
1223 where
1224 T: GraphQLType<S> + ToInputValue<S> + FromInputValue<S>,
1225 S: ScalarValue,
1226 {
1227 Argument::new(name, self.get_type::<T>(info)).default_value(value.to_input_value())
1228 }
1229
1230 fn insert_placeholder(&mut self, name: Name, of_type: Type<'r>) {
1231 self.types
1232 .entry(name)
1233 .or_insert(MetaType::Placeholder(PlaceholderMeta { of_type }));
1234 }
1235
1236 pub fn build_scalar_type<T>(&mut self, info: &T::TypeInfo) -> ScalarMeta<'r, S>
1238 where
1239 T: GraphQLType<S> + FromInputValue<S> + ParseScalarValue<S>,
1240 T::Error: IntoFieldError<S>,
1241 S: ScalarValue,
1242 {
1243 let name = T::name(info).expect("Scalar types must be named. Implement `name()`");
1244
1245 ScalarMeta::new::<T>(Cow::Owned(name.into()))
1246 }
1247
1248 pub fn build_list_type<T>(
1253 &mut self,
1254 info: &T::TypeInfo,
1255 expected_size: Option<usize>,
1256 ) -> ListMeta<'r>
1257 where
1258 T: GraphQLType<S> + ?Sized,
1259 S: ScalarValue,
1260 {
1261 let of_type = self.get_type::<T>(info);
1262 ListMeta::new(of_type, expected_size)
1263 }
1264
1265 pub fn build_nullable_type<T>(&mut self, info: &T::TypeInfo) -> NullableMeta<'r>
1267 where
1268 T: GraphQLType<S> + ?Sized,
1269 S: ScalarValue,
1270 {
1271 let of_type = self.get_type::<T>(info);
1272 NullableMeta::new(of_type)
1273 }
1274
1275 pub fn build_object_type<T>(
1277 &mut self,
1278 info: &T::TypeInfo,
1279 fields: &[Field<'r, S>],
1280 ) -> ObjectMeta<'r, S>
1281 where
1282 T: GraphQLType<S> + ?Sized,
1283 S: ScalarValue,
1284 {
1285 let name = T::name(info).expect("Object types must be named. Implement name()");
1286
1287 let mut v = fields.to_vec();
1288 v.push(self.field::<String>("__typename", &()));
1289 ObjectMeta::new(Cow::Owned(name.into()), &v)
1290 }
1291
1292 pub fn build_enum_type<T>(
1294 &mut self,
1295 info: &T::TypeInfo,
1296 values: &[EnumValue],
1297 ) -> EnumMeta<'r, S>
1298 where
1299 T: GraphQLType<S> + FromInputValue<S>,
1300 T::Error: IntoFieldError<S>,
1301 S: ScalarValue,
1302 {
1303 let name = T::name(info).expect("Enum types must be named. Implement `name()`");
1304
1305 EnumMeta::new::<T>(Cow::Owned(name.into()), values)
1306 }
1307
1308 pub fn build_interface_type<T>(
1310 &mut self,
1311 info: &T::TypeInfo,
1312 fields: &[Field<'r, S>],
1313 ) -> InterfaceMeta<'r, S>
1314 where
1315 T: GraphQLType<S> + ?Sized,
1316 S: ScalarValue,
1317 {
1318 let name = T::name(info).expect("Interface types must be named. Implement name()");
1319
1320 let mut v = fields.to_vec();
1321 v.push(self.field::<String>("__typename", &()));
1322 InterfaceMeta::new(Cow::Owned(name.into()), &v)
1323 }
1324
1325 pub fn build_union_type<T>(&mut self, info: &T::TypeInfo, types: &[Type<'r>]) -> UnionMeta<'r>
1327 where
1328 T: GraphQLType<S> + ?Sized,
1329 S: ScalarValue,
1330 {
1331 let name = T::name(info).expect("Union types must be named. Implement name()");
1332
1333 UnionMeta::new(Cow::Owned(name.into()), types)
1334 }
1335
1336 pub fn build_input_object_type<T>(
1338 &mut self,
1339 info: &T::TypeInfo,
1340 args: &[Argument<'r, S>],
1341 ) -> InputObjectMeta<'r, S>
1342 where
1343 T: GraphQLType<S> + FromInputValue<S>,
1344 T::Error: IntoFieldError<S>,
1345 S: ScalarValue,
1346 {
1347 let name = T::name(info).expect("Input object types must be named. Implement name()");
1348
1349 InputObjectMeta::new::<T>(Cow::Owned(name.into()), args)
1350 }
1351}