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