1use std::{
4 any::{Any, TypeId},
5 collections::HashMap,
6 fmt::{self, Debug, Display, Formatter},
7 ops::Deref,
8 sync::{Arc, Mutex},
9};
10
11use async_graphql_parser::types::ConstDirective;
12use async_graphql_value::{Value as InputValue, Variables};
13use indexmap::IndexMap;
14use rustc_hash::FxHashMap;
15use serde::{
16 Serialize,
17 ser::{SerializeSeq, Serializer},
18};
19
20use crate::{
21 Error, InputType, Lookahead, Name, OneofObjectType, PathSegment, Pos, Positioned, Result,
22 ServerError, ServerResult, UploadValue, Value,
23 extensions::Extensions,
24 parser::types::{
25 Directive, Field, FragmentDefinition, OperationDefinition, Selection, SelectionSet,
26 },
27 schema::{IntrospectionMode, SchemaEnv},
28};
29
30pub trait DataContext<'a> {
32 fn data<D: Any + Send + Sync>(&self) -> Result<&'a D>;
41
42 fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D;
48
49 fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D>;
52}
53
54#[derive(Default)]
58pub struct Data(FxHashMap<TypeId, Box<dyn Any + Sync + Send>>);
59
60impl Deref for Data {
61 type Target = FxHashMap<TypeId, Box<dyn Any + Sync + Send>>;
62
63 fn deref(&self) -> &Self::Target {
64 &self.0
65 }
66}
67
68impl Data {
69 pub fn insert<D: Any + Send + Sync>(&mut self, data: D) {
71 self.0.insert(TypeId::of::<D>(), Box::new(data));
72 }
73
74 pub(crate) fn merge(&mut self, other: Data) {
75 self.0.extend(other.0);
76 }
77}
78
79impl Debug for Data {
80 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
81 f.debug_tuple("Data").finish()
82 }
83}
84
85pub type ContextSelectionSet<'a> = ContextBase<'a, &'a Positioned<SelectionSet>>;
87
88pub type Context<'a> = ContextBase<'a, &'a Positioned<Field>>;
90
91pub type ContextDirective<'a> = ContextBase<'a, &'a Positioned<Directive>>;
93
94#[derive(Debug, Clone, Copy, Serialize)]
99#[serde(untagged)]
100pub enum QueryPathSegment<'a> {
101 Index(usize),
103 Name(&'a str),
105}
106
107#[derive(Debug, Clone, Copy)]
111pub struct QueryPathNode<'a> {
112 pub parent: Option<&'a QueryPathNode<'a>>,
114
115 pub segment: QueryPathSegment<'a>,
117}
118
119impl serde::Serialize for QueryPathNode<'_> {
120 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
121 let mut seq = serializer.serialize_seq(None)?;
122 self.try_for_each(|segment| seq.serialize_element(segment))?;
123 seq.end()
124 }
125}
126
127impl Display for QueryPathNode<'_> {
128 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
129 let mut first = true;
130 self.try_for_each(|segment| {
131 if !first {
132 write!(f, ".")?;
133 }
134 first = false;
135
136 match segment {
137 QueryPathSegment::Index(idx) => write!(f, "{}", *idx),
138 QueryPathSegment::Name(name) => write!(f, "{}", name),
139 }
140 })
141 }
142}
143
144impl<'a> QueryPathNode<'a> {
145 pub fn field_name(&self) -> &str {
150 std::iter::once(self)
151 .chain(self.parents())
152 .find_map(|node| match node.segment {
153 QueryPathSegment::Name(name) => Some(name),
154 QueryPathSegment::Index(_) => None,
155 })
156 .unwrap()
157 }
158
159 #[must_use]
161 pub fn to_string_vec(self) -> Vec<String> {
162 let mut res = Vec::new();
163 self.for_each(|s| {
164 res.push(match s {
165 QueryPathSegment::Name(name) => (*name).to_string(),
166 QueryPathSegment::Index(idx) => idx.to_string(),
167 });
168 });
169 res
170 }
171
172 pub fn parents(&self) -> Parents<'_> {
174 Parents(self)
175 }
176
177 pub(crate) fn for_each<F: FnMut(&QueryPathSegment<'a>)>(&self, mut f: F) {
178 let _ = self.try_for_each::<std::convert::Infallible, _>(|segment| {
179 f(segment);
180 Ok(())
181 });
182 }
183
184 pub(crate) fn try_for_each<E, F: FnMut(&QueryPathSegment<'a>) -> Result<(), E>>(
185 &self,
186 mut f: F,
187 ) -> Result<(), E> {
188 self.try_for_each_ref(&mut f)
189 }
190
191 fn try_for_each_ref<E, F: FnMut(&QueryPathSegment<'a>) -> Result<(), E>>(
192 &self,
193 f: &mut F,
194 ) -> Result<(), E> {
195 if let Some(parent) = &self.parent {
196 parent.try_for_each_ref(f)?;
197 }
198 f(&self.segment)
199 }
200}
201
202#[derive(Debug, Clone)]
205pub struct Parents<'a>(&'a QueryPathNode<'a>);
206
207impl<'a> Parents<'a> {
208 #[must_use]
211 pub fn current(&self) -> &'a QueryPathNode<'a> {
212 self.0
213 }
214}
215
216impl<'a> Iterator for Parents<'a> {
217 type Item = &'a QueryPathNode<'a>;
218
219 fn next(&mut self) -> Option<Self::Item> {
220 let parent = self.0.parent;
221 if let Some(parent) = parent {
222 self.0 = parent;
223 }
224 parent
225 }
226}
227
228impl std::iter::FusedIterator for Parents<'_> {}
229
230#[derive(Clone)]
234pub struct ContextBase<'a, T> {
235 pub path_node: Option<QueryPathNode<'a>>,
237 pub(crate) is_for_introspection: bool,
239 #[doc(hidden)]
240 pub item: T,
241 #[doc(hidden)]
242 pub schema_env: &'a SchemaEnv,
243 #[doc(hidden)]
244 pub query_env: &'a QueryEnv,
245 #[doc(hidden)]
246 pub execute_data: Option<&'a Data>,
247}
248
249#[doc(hidden)]
250pub struct QueryEnvInner {
251 pub extensions: Extensions,
252 pub variables: Variables,
253 pub operation_name: Option<String>,
254 pub operation: Positioned<OperationDefinition>,
255 pub fragments: HashMap<Name, Positioned<FragmentDefinition>>,
256 pub uploads: Vec<UploadValue>,
257 pub session_data: Arc<Data>,
258 pub query_data: Arc<Data>,
259 pub http_headers: Mutex<http::HeaderMap>,
260 pub introspection_mode: IntrospectionMode,
261 pub errors: Mutex<Vec<ServerError>>,
262}
263
264#[doc(hidden)]
265#[derive(Clone)]
266pub struct QueryEnv(Arc<QueryEnvInner>);
267
268impl Deref for QueryEnv {
269 type Target = QueryEnvInner;
270
271 fn deref(&self) -> &Self::Target {
272 &self.0
273 }
274}
275
276impl QueryEnv {
277 #[doc(hidden)]
278 pub fn new(inner: QueryEnvInner) -> QueryEnv {
279 QueryEnv(Arc::new(inner))
280 }
281
282 #[doc(hidden)]
283 pub fn create_context<'a, T>(
284 &'a self,
285 schema_env: &'a SchemaEnv,
286 path_node: Option<QueryPathNode<'a>>,
287 item: T,
288 execute_data: Option<&'a Data>,
289 ) -> ContextBase<'a, T> {
290 ContextBase {
291 path_node,
292 is_for_introspection: false,
293 item,
294 schema_env,
295 query_env: self,
296 execute_data,
297 }
298 }
299}
300
301impl<'a, T> DataContext<'a> for ContextBase<'a, T> {
302 fn data<D: Any + Send + Sync>(&self) -> Result<&'a D> {
303 ContextBase::data::<D>(self)
304 }
305
306 fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D {
307 ContextBase::data_unchecked::<D>(self)
308 }
309
310 fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D> {
311 ContextBase::data_opt::<D>(self)
312 }
313}
314
315impl<'a, T> ContextBase<'a, T> {
316 #[doc(hidden)]
317 pub fn with_field(
318 &'a self,
319 field: &'a Positioned<Field>,
320 ) -> ContextBase<'a, &'a Positioned<Field>> {
321 ContextBase {
322 path_node: Some(QueryPathNode {
323 parent: self.path_node.as_ref(),
324 segment: QueryPathSegment::Name(&field.node.response_key().node),
325 }),
326 is_for_introspection: self.is_for_introspection,
327 item: field,
328 schema_env: self.schema_env,
329 query_env: self.query_env,
330 execute_data: self.execute_data,
331 }
332 }
333
334 #[doc(hidden)]
335 pub fn with_selection_set(
336 &self,
337 selection_set: &'a Positioned<SelectionSet>,
338 ) -> ContextBase<'a, &'a Positioned<SelectionSet>> {
339 ContextBase {
340 path_node: self.path_node,
341 is_for_introspection: self.is_for_introspection,
342 item: selection_set,
343 schema_env: self.schema_env,
344 query_env: self.query_env,
345 execute_data: self.execute_data,
346 }
347 }
348
349 #[doc(hidden)]
350 pub fn set_error_path(&self, error: ServerError) -> ServerError {
351 if let Some(node) = self.path_node {
352 let mut path = Vec::new();
353 node.for_each(|current_node| {
354 path.push(match current_node {
355 QueryPathSegment::Name(name) => PathSegment::Field((*name).to_string()),
356 QueryPathSegment::Index(idx) => PathSegment::Index(*idx),
357 })
358 });
359 ServerError { path, ..error }
360 } else {
361 error
362 }
363 }
364
365 pub fn add_error(&self, error: ServerError) {
370 self.query_env.errors.lock().unwrap().push(error);
371 }
372
373 pub fn data<D: Any + Send + Sync>(&self) -> Result<&'a D> {
382 self.data_opt::<D>().ok_or_else(|| {
383 Error::new(format!(
384 "Data `{}` does not exist.",
385 std::any::type_name::<D>()
386 ))
387 })
388 }
389
390 pub fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D {
396 self.data_opt::<D>()
397 .unwrap_or_else(|| panic!("Data `{}` does not exist.", std::any::type_name::<D>()))
398 }
399
400 pub fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D> {
403 self.execute_data
404 .as_ref()
405 .and_then(|execute_data| execute_data.get(&TypeId::of::<D>()))
406 .or_else(|| self.query_env.query_data.0.get(&TypeId::of::<D>()))
407 .or_else(|| self.query_env.session_data.0.get(&TypeId::of::<D>()))
408 .or_else(|| self.schema_env.data.0.get(&TypeId::of::<D>()))
409 .and_then(|d| d.downcast_ref::<D>())
410 }
411
412 pub fn http_header_contains(&self, key: impl http::header::AsHeaderName) -> bool {
438 self.query_env
439 .http_headers
440 .lock()
441 .unwrap()
442 .contains_key(key)
443 }
444
445 pub fn insert_http_header(
487 &self,
488 name: impl http::header::IntoHeaderName,
489 value: impl TryInto<http::HeaderValue>,
490 ) -> Option<http::HeaderValue> {
491 if let Ok(value) = value.try_into() {
492 self.query_env
493 .http_headers
494 .lock()
495 .unwrap()
496 .insert(name, value)
497 } else {
498 None
499 }
500 }
501
502 pub fn append_http_header(
538 &self,
539 name: impl http::header::IntoHeaderName,
540 value: impl TryInto<http::HeaderValue>,
541 ) -> bool {
542 if let Ok(value) = value.try_into() {
543 self.query_env
544 .http_headers
545 .lock()
546 .unwrap()
547 .append(name, value)
548 } else {
549 false
550 }
551 }
552
553 fn var_value(&self, name: &str, pos: Pos) -> ServerResult<Option<Value>> {
554 let def = self
555 .query_env
556 .operation
557 .node
558 .variable_definitions
559 .iter()
560 .find(|def| def.node.name.node == name)
561 .ok_or_else(|| {
562 ServerError::new(format!("Variable {} is not defined.", name), Some(pos))
563 })?;
564
565 Ok(self
568 .query_env
569 .variables
570 .get(&def.node.name.node)
571 .cloned()
572 .or_else(|| {
573 def.node
574 .default_value
575 .as_ref()
576 .map(|value| value.node.clone())
577 }))
578 }
579
580 fn resolve_input_value_inner(
581 &self,
582 value: InputValue,
583 pos: Pos,
584 ) -> ServerResult<Option<Value>> {
585 Ok(match value {
586 InputValue::Variable(name) => self.var_value(&name, pos)?,
587 InputValue::Null => Some(Value::Null),
588 InputValue::Number(num) => Some(Value::Number(num)),
589 InputValue::String(value) => Some(Value::String(value)),
590 InputValue::Boolean(value) => Some(Value::Boolean(value)),
591 InputValue::Binary(value) => Some(Value::Binary(value)),
592 InputValue::Enum(value) => Some(Value::Enum(value)),
593 InputValue::List(items) => {
594 let mut resolved_items = Vec::with_capacity(items.len());
595 for item in items {
596 resolved_items.push(
598 self.resolve_input_value_inner(item, pos)?
599 .unwrap_or(Value::Null),
600 );
601 }
602 Some(Value::List(resolved_items))
603 }
604 InputValue::Object(object) => {
605 let mut resolved_object = IndexMap::with_capacity(object.len());
606 for (name, value) in object {
607 if let Some(value) = self.resolve_input_value_inner(value, pos)? {
609 resolved_object.insert(name, value);
610 }
611 }
612 Some(Value::Object(resolved_object))
613 }
614 })
615 }
616
617 pub(crate) fn resolve_input_value(
618 &self,
619 value: Positioned<InputValue>,
620 ) -> ServerResult<Option<Value>> {
621 self.resolve_input_value_inner(value.node, value.pos)
622 }
623
624 #[doc(hidden)]
625 fn get_param_value<Q: InputType>(
626 &self,
627 arguments: &[(Positioned<Name>, Positioned<InputValue>)],
628 name: &str,
629 default: Option<fn() -> Q>,
630 ) -> ServerResult<(Pos, Q)> {
631 let value = arguments
632 .iter()
633 .find(|(n, _)| n.node.as_str() == name)
634 .map(|(_, value)| value)
635 .cloned();
636 if value.is_none()
637 && let Some(default) = default
638 {
639 return Ok((Pos::default(), default()));
640 }
641 let (pos, value) = match value {
642 Some(value) => (value.pos, self.resolve_input_value(value)?),
643 None => (Pos::default(), None),
644 };
645 InputType::parse(value)
646 .map(|value| (pos, value))
647 .map_err(|e| e.into_server_error(pos))
648 }
649
650 #[doc(hidden)]
651 #[must_use]
652 pub fn with_index(&'a self, idx: usize) -> ContextBase<'a, T>
653 where
654 T: Copy,
655 {
656 ContextBase {
657 path_node: Some(QueryPathNode {
658 parent: self.path_node.as_ref(),
659 segment: QueryPathSegment::Index(idx),
660 }),
661 is_for_introspection: self.is_for_introspection,
662 item: self.item,
663 schema_env: self.schema_env,
664 query_env: self.query_env,
665 execute_data: self.execute_data,
666 }
667 }
668}
669
670impl<'a> ContextBase<'a, &'a Positioned<Field>> {
671 #[doc(hidden)]
672 pub fn param_value<T: InputType>(
673 &self,
674 name: &str,
675 default: Option<fn() -> T>,
676 ) -> ServerResult<(Pos, T)> {
677 self.get_param_value(&self.item.node.arguments, name, default)
678 }
679
680 #[doc(hidden)]
681 pub fn oneof_param_value<T: OneofObjectType>(&self) -> ServerResult<(Pos, T)> {
682 use indexmap::IndexMap;
683
684 let mut map = IndexMap::new();
685
686 for (name, value) in &self.item.node.arguments {
687 if let Some(value) = self.resolve_input_value(value.clone())? {
690 map.insert(name.node.clone(), value);
691 }
692 }
693
694 InputType::parse(Some(Value::Object(map)))
695 .map(|value| (self.item.pos, value))
696 .map_err(|e| e.into_server_error(self.item.pos))
697 }
698
699 pub fn look_ahead(&self) -> Lookahead<'_> {
736 Lookahead::new(&self.query_env.fragments, &self.item.node, self)
737 }
738
739 pub fn field(&self) -> SelectionField<'_> {
781 SelectionField {
782 fragments: &self.query_env.fragments,
783 field: &self.item.node,
784 context: self,
785 }
786 }
787}
788
789impl<'a> ContextBase<'a, &'a Positioned<Directive>> {
790 #[doc(hidden)]
791 pub fn param_value<T: InputType>(
792 &self,
793 name: &str,
794 default: Option<fn() -> T>,
795 ) -> ServerResult<(Pos, T)> {
796 self.get_param_value(&self.item.node.arguments, name, default)
797 }
798}
799
800#[derive(Clone, Copy)]
802pub struct SelectionField<'a> {
803 pub(crate) fragments: &'a HashMap<Name, Positioned<FragmentDefinition>>,
804 pub(crate) field: &'a Field,
805 pub(crate) context: &'a Context<'a>,
806}
807
808impl<'a> SelectionField<'a> {
809 #[inline]
811 pub fn name(&self) -> &'a str {
812 self.field.name.node.as_str()
813 }
814
815 #[inline]
817 pub fn alias(&self) -> Option<&'a str> {
818 self.field.alias.as_ref().map(|alias| alias.node.as_str())
819 }
820
821 pub fn directives(&self) -> ServerResult<Vec<ConstDirective>> {
823 let mut directives = Vec::with_capacity(self.field.directives.len());
824
825 for directive in &self.field.directives {
826 let directive = &directive.node;
827
828 let mut arguments = Vec::with_capacity(directive.arguments.len());
829 for (name, value) in &directive.arguments {
830 if let Some(resolved_value) = self.context.resolve_input_value(value.clone())? {
832 arguments.push((name.clone(), value.position_node(resolved_value)));
833 }
834 }
835
836 directives.push(ConstDirective {
837 name: directive.name.clone(),
838 arguments,
839 });
840 }
841
842 Ok(directives)
843 }
844
845 pub fn arguments(&self) -> ServerResult<Vec<(Name, Value)>> {
847 let mut arguments = Vec::with_capacity(self.field.arguments.len());
848 for (name, value) in &self.field.arguments {
849 if let Some(value) = self.context.resolve_input_value(value.clone())? {
851 arguments.push((name.node.clone(), value));
852 }
853 }
854 Ok(arguments)
855 }
856
857 pub fn selection_set(&self) -> impl Iterator<Item = SelectionField<'a>> {
859 SelectionFieldsIter {
860 fragments: self.fragments,
861 iter: vec![self.field.selection_set.node.items.iter()],
862 context: self.context,
863 }
864 }
865}
866
867impl Debug for SelectionField<'_> {
868 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
869 struct DebugSelectionSet<'a>(Vec<SelectionField<'a>>);
870
871 impl Debug for DebugSelectionSet<'_> {
872 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
873 f.debug_list().entries(&self.0).finish()
874 }
875 }
876
877 f.debug_struct(self.name())
878 .field("name", &self.name())
879 .field(
880 "selection_set",
881 &DebugSelectionSet(self.selection_set().collect()),
882 )
883 .finish()
884 }
885}
886
887struct SelectionFieldsIter<'a> {
888 fragments: &'a HashMap<Name, Positioned<FragmentDefinition>>,
889 iter: Vec<std::slice::Iter<'a, Positioned<Selection>>>,
890 context: &'a Context<'a>,
891}
892
893impl<'a> Iterator for SelectionFieldsIter<'a> {
894 type Item = SelectionField<'a>;
895
896 fn next(&mut self) -> Option<Self::Item> {
897 loop {
898 let it = self.iter.last_mut()?;
899 let item = it.next();
900
901 match item {
902 Some(selection) => match &selection.node {
903 Selection::Field(field) => {
904 return Some(SelectionField {
905 fragments: self.fragments,
906 field: &field.node,
907 context: self.context,
908 });
909 }
910 Selection::FragmentSpread(fragment_spread) => {
911 if let Some(fragment) =
912 self.fragments.get(&fragment_spread.node.fragment_name.node)
913 {
914 self.iter
915 .push(fragment.node.selection_set.node.items.iter());
916 }
917 }
918 Selection::InlineFragment(inline_fragment) => {
919 self.iter
920 .push(inline_fragment.node.selection_set.node.items.iter());
921 }
922 },
923 None => {
924 self.iter.pop();
925 }
926 }
927 }
928 }
929}