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 fnv::FnvHashMap;
14use serde::{
15 Serialize,
16 ser::{SerializeSeq, Serializer},
17};
18
19use crate::{
20 Error, InputType, Lookahead, Name, OneofObjectType, PathSegment, Pos, Positioned, Result,
21 ServerError, ServerResult, UploadValue, Value,
22 extensions::Extensions,
23 parser::types::{
24 Directive, Field, FragmentDefinition, OperationDefinition, Selection, SelectionSet,
25 },
26 schema::{IntrospectionMode, SchemaEnv},
27};
28
29pub trait DataContext<'a> {
31 fn data<D: Any + Send + Sync>(&self) -> Result<&'a D>;
40
41 fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D;
47
48 fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D>;
51}
52
53#[derive(Default)]
57pub struct Data(FnvHashMap<TypeId, Box<dyn Any + Sync + Send>>);
58
59impl Deref for Data {
60 type Target = FnvHashMap<TypeId, Box<dyn Any + Sync + Send>>;
61
62 fn deref(&self) -> &Self::Target {
63 &self.0
64 }
65}
66
67impl Data {
68 pub fn insert<D: Any + Send + Sync>(&mut self, data: D) {
70 self.0.insert(TypeId::of::<D>(), Box::new(data));
71 }
72
73 pub(crate) fn merge(&mut self, other: Data) {
74 self.0.extend(other.0);
75 }
76}
77
78impl Debug for Data {
79 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
80 f.debug_tuple("Data").finish()
81 }
82}
83
84pub type ContextSelectionSet<'a> = ContextBase<'a, &'a Positioned<SelectionSet>>;
86
87pub type Context<'a> = ContextBase<'a, &'a Positioned<Field>>;
89
90pub type ContextDirective<'a> = ContextBase<'a, &'a Positioned<Directive>>;
92
93#[derive(Debug, Clone, Copy, Serialize)]
98#[serde(untagged)]
99pub enum QueryPathSegment<'a> {
100 Index(usize),
102 Name(&'a str),
104}
105
106#[derive(Debug, Clone, Copy)]
110pub struct QueryPathNode<'a> {
111 pub parent: Option<&'a QueryPathNode<'a>>,
113
114 pub segment: QueryPathSegment<'a>,
116}
117
118impl serde::Serialize for QueryPathNode<'_> {
119 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
120 let mut seq = serializer.serialize_seq(None)?;
121 self.try_for_each(|segment| seq.serialize_element(segment))?;
122 seq.end()
123 }
124}
125
126impl Display for QueryPathNode<'_> {
127 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
128 let mut first = true;
129 self.try_for_each(|segment| {
130 if !first {
131 write!(f, ".")?;
132 }
133 first = false;
134
135 match segment {
136 QueryPathSegment::Index(idx) => write!(f, "{}", *idx),
137 QueryPathSegment::Name(name) => write!(f, "{}", name),
138 }
139 })
140 }
141}
142
143impl<'a> QueryPathNode<'a> {
144 pub fn field_name(&self) -> &str {
149 std::iter::once(self)
150 .chain(self.parents())
151 .find_map(|node| match node.segment {
152 QueryPathSegment::Name(name) => Some(name),
153 QueryPathSegment::Index(_) => None,
154 })
155 .unwrap()
156 }
157
158 #[must_use]
160 pub fn to_string_vec(self) -> Vec<String> {
161 let mut res = Vec::new();
162 self.for_each(|s| {
163 res.push(match s {
164 QueryPathSegment::Name(name) => (*name).to_string(),
165 QueryPathSegment::Index(idx) => idx.to_string(),
166 });
167 });
168 res
169 }
170
171 pub fn parents(&self) -> Parents<'_> {
173 Parents(self)
174 }
175
176 pub(crate) fn for_each<F: FnMut(&QueryPathSegment<'a>)>(&self, mut f: F) {
177 let _ = self.try_for_each::<std::convert::Infallible, _>(|segment| {
178 f(segment);
179 Ok(())
180 });
181 }
182
183 pub(crate) fn try_for_each<E, F: FnMut(&QueryPathSegment<'a>) -> Result<(), E>>(
184 &self,
185 mut f: F,
186 ) -> Result<(), E> {
187 self.try_for_each_ref(&mut f)
188 }
189
190 fn try_for_each_ref<E, F: FnMut(&QueryPathSegment<'a>) -> Result<(), E>>(
191 &self,
192 f: &mut F,
193 ) -> Result<(), E> {
194 if let Some(parent) = &self.parent {
195 parent.try_for_each_ref(f)?;
196 }
197 f(&self.segment)
198 }
199}
200
201#[derive(Debug, Clone)]
204pub struct Parents<'a>(&'a QueryPathNode<'a>);
205
206impl<'a> Parents<'a> {
207 #[must_use]
210 pub fn current(&self) -> &'a QueryPathNode<'a> {
211 self.0
212 }
213}
214
215impl<'a> Iterator for Parents<'a> {
216 type Item = &'a QueryPathNode<'a>;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 let parent = self.0.parent;
220 if let Some(parent) = parent {
221 self.0 = parent;
222 }
223 parent
224 }
225}
226
227impl std::iter::FusedIterator for Parents<'_> {}
228
229#[derive(Clone)]
233pub struct ContextBase<'a, T> {
234 pub path_node: Option<QueryPathNode<'a>>,
236 pub(crate) is_for_introspection: bool,
238 #[doc(hidden)]
239 pub item: T,
240 #[doc(hidden)]
241 pub schema_env: &'a SchemaEnv,
242 #[doc(hidden)]
243 pub query_env: &'a QueryEnv,
244 #[doc(hidden)]
245 pub execute_data: Option<&'a Data>,
246}
247
248#[doc(hidden)]
249pub struct QueryEnvInner {
250 pub extensions: Extensions,
251 pub variables: Variables,
252 pub operation_name: Option<String>,
253 pub operation: Positioned<OperationDefinition>,
254 pub fragments: HashMap<Name, Positioned<FragmentDefinition>>,
255 pub uploads: Vec<UploadValue>,
256 pub session_data: Arc<Data>,
257 pub query_data: Arc<Data>,
258 pub http_headers: Mutex<http::HeaderMap>,
259 pub introspection_mode: IntrospectionMode,
260 pub errors: Mutex<Vec<ServerError>>,
261}
262
263#[doc(hidden)]
264#[derive(Clone)]
265pub struct QueryEnv(Arc<QueryEnvInner>);
266
267impl Deref for QueryEnv {
268 type Target = QueryEnvInner;
269
270 fn deref(&self) -> &Self::Target {
271 &self.0
272 }
273}
274
275impl QueryEnv {
276 #[doc(hidden)]
277 pub fn new(inner: QueryEnvInner) -> QueryEnv {
278 QueryEnv(Arc::new(inner))
279 }
280
281 #[doc(hidden)]
282 pub fn create_context<'a, T>(
283 &'a self,
284 schema_env: &'a SchemaEnv,
285 path_node: Option<QueryPathNode<'a>>,
286 item: T,
287 execute_data: Option<&'a Data>,
288 ) -> ContextBase<'a, T> {
289 ContextBase {
290 path_node,
291 is_for_introspection: false,
292 item,
293 schema_env,
294 query_env: self,
295 execute_data,
296 }
297 }
298}
299
300impl<'a, T> DataContext<'a> for ContextBase<'a, T> {
301 fn data<D: Any + Send + Sync>(&self) -> Result<&'a D> {
302 ContextBase::data::<D>(self)
303 }
304
305 fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D {
306 ContextBase::data_unchecked::<D>(self)
307 }
308
309 fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D> {
310 ContextBase::data_opt::<D>(self)
311 }
312}
313
314impl<'a, T> ContextBase<'a, T> {
315 #[doc(hidden)]
316 pub fn with_field(
317 &'a self,
318 field: &'a Positioned<Field>,
319 ) -> ContextBase<'a, &'a Positioned<Field>> {
320 ContextBase {
321 path_node: Some(QueryPathNode {
322 parent: self.path_node.as_ref(),
323 segment: QueryPathSegment::Name(&field.node.response_key().node),
324 }),
325 is_for_introspection: self.is_for_introspection,
326 item: field,
327 schema_env: self.schema_env,
328 query_env: self.query_env,
329 execute_data: self.execute_data,
330 }
331 }
332
333 #[doc(hidden)]
334 pub fn with_selection_set(
335 &self,
336 selection_set: &'a Positioned<SelectionSet>,
337 ) -> ContextBase<'a, &'a Positioned<SelectionSet>> {
338 ContextBase {
339 path_node: self.path_node,
340 is_for_introspection: self.is_for_introspection,
341 item: selection_set,
342 schema_env: self.schema_env,
343 query_env: self.query_env,
344 execute_data: self.execute_data,
345 }
346 }
347
348 #[doc(hidden)]
349 pub fn set_error_path(&self, error: ServerError) -> ServerError {
350 if let Some(node) = self.path_node {
351 let mut path = Vec::new();
352 node.for_each(|current_node| {
353 path.push(match current_node {
354 QueryPathSegment::Name(name) => PathSegment::Field((*name).to_string()),
355 QueryPathSegment::Index(idx) => PathSegment::Index(*idx),
356 })
357 });
358 ServerError { path, ..error }
359 } else {
360 error
361 }
362 }
363
364 pub fn add_error(&self, error: ServerError) {
369 self.query_env.errors.lock().unwrap().push(error);
370 }
371
372 pub fn data<D: Any + Send + Sync>(&self) -> Result<&'a D> {
381 self.data_opt::<D>().ok_or_else(|| {
382 Error::new(format!(
383 "Data `{}` does not exist.",
384 std::any::type_name::<D>()
385 ))
386 })
387 }
388
389 pub fn data_unchecked<D: Any + Send + Sync>(&self) -> &'a D {
395 self.data_opt::<D>()
396 .unwrap_or_else(|| panic!("Data `{}` does not exist.", std::any::type_name::<D>()))
397 }
398
399 pub fn data_opt<D: Any + Send + Sync>(&self) -> Option<&'a D> {
402 self.execute_data
403 .as_ref()
404 .and_then(|execute_data| execute_data.get(&TypeId::of::<D>()))
405 .or_else(|| self.query_env.query_data.0.get(&TypeId::of::<D>()))
406 .or_else(|| self.query_env.session_data.0.get(&TypeId::of::<D>()))
407 .or_else(|| self.schema_env.data.0.get(&TypeId::of::<D>()))
408 .and_then(|d| d.downcast_ref::<D>())
409 }
410
411 pub fn http_header_contains(&self, key: impl http::header::AsHeaderName) -> bool {
437 self.query_env
438 .http_headers
439 .lock()
440 .unwrap()
441 .contains_key(key)
442 }
443
444 pub fn insert_http_header(
486 &self,
487 name: impl http::header::IntoHeaderName,
488 value: impl TryInto<http::HeaderValue>,
489 ) -> Option<http::HeaderValue> {
490 if let Ok(value) = value.try_into() {
491 self.query_env
492 .http_headers
493 .lock()
494 .unwrap()
495 .insert(name, value)
496 } else {
497 None
498 }
499 }
500
501 pub fn append_http_header(
537 &self,
538 name: impl http::header::IntoHeaderName,
539 value: impl TryInto<http::HeaderValue>,
540 ) -> bool {
541 if let Ok(value) = value.try_into() {
542 self.query_env
543 .http_headers
544 .lock()
545 .unwrap()
546 .append(name, value)
547 } else {
548 false
549 }
550 }
551
552 fn var_value(&self, name: &str, pos: Pos) -> ServerResult<Value> {
553 self.query_env
554 .operation
555 .node
556 .variable_definitions
557 .iter()
558 .find(|def| def.node.name.node == name)
559 .and_then(|def| {
560 self.query_env
561 .variables
562 .get(&def.node.name.node)
563 .or_else(|| def.node.default_value())
564 })
565 .cloned()
566 .ok_or_else(|| {
567 ServerError::new(format!("Variable {} is not defined.", name), Some(pos))
568 })
569 }
570
571 pub(crate) fn resolve_input_value(&self, value: Positioned<InputValue>) -> ServerResult<Value> {
572 let pos = value.pos;
573 value
574 .node
575 .into_const_with(|name| self.var_value(&name, pos))
576 }
577
578 #[doc(hidden)]
579 fn get_param_value<Q: InputType>(
580 &self,
581 arguments: &[(Positioned<Name>, Positioned<InputValue>)],
582 name: &str,
583 default: Option<fn() -> Q>,
584 ) -> ServerResult<(Pos, Q)> {
585 let value = arguments
586 .iter()
587 .find(|(n, _)| n.node.as_str() == name)
588 .map(|(_, value)| value)
589 .cloned();
590 if value.is_none() {
591 if let Some(default) = default {
592 return Ok((Pos::default(), default()));
593 }
594 }
595 let (pos, value) = match value {
596 Some(value) => (value.pos, Some(self.resolve_input_value(value)?)),
597 None => (Pos::default(), None),
598 };
599 InputType::parse(value)
600 .map(|value| (pos, value))
601 .map_err(|e| e.into_server_error(pos))
602 }
603
604 #[doc(hidden)]
605 #[must_use]
606 pub fn with_index(&'a self, idx: usize) -> ContextBase<'a, T>
607 where
608 T: Copy,
609 {
610 ContextBase {
611 path_node: Some(QueryPathNode {
612 parent: self.path_node.as_ref(),
613 segment: QueryPathSegment::Index(idx),
614 }),
615 is_for_introspection: self.is_for_introspection,
616 item: self.item,
617 schema_env: self.schema_env,
618 query_env: self.query_env,
619 execute_data: self.execute_data,
620 }
621 }
622}
623
624impl<'a> ContextBase<'a, &'a Positioned<Field>> {
625 #[doc(hidden)]
626 pub fn param_value<T: InputType>(
627 &self,
628 name: &str,
629 default: Option<fn() -> T>,
630 ) -> ServerResult<(Pos, T)> {
631 self.get_param_value(&self.item.node.arguments, name, default)
632 }
633
634 #[doc(hidden)]
635 pub fn oneof_param_value<T: OneofObjectType>(&self) -> ServerResult<(Pos, T)> {
636 use indexmap::IndexMap;
637
638 let mut map = IndexMap::new();
639
640 for (name, value) in &self.item.node.arguments {
641 let value = self.resolve_input_value(value.clone())?;
642 map.insert(name.node.clone(), value);
643 }
644
645 InputType::parse(Some(Value::Object(map)))
646 .map(|value| (self.item.pos, value))
647 .map_err(|e| e.into_server_error(self.item.pos))
648 }
649
650 pub fn look_ahead(&self) -> Lookahead {
687 Lookahead::new(&self.query_env.fragments, &self.item.node, self)
688 }
689
690 pub fn field(&self) -> SelectionField {
732 SelectionField {
733 fragments: &self.query_env.fragments,
734 field: &self.item.node,
735 context: self,
736 }
737 }
738}
739
740impl<'a> ContextBase<'a, &'a Positioned<Directive>> {
741 #[doc(hidden)]
742 pub fn param_value<T: InputType>(
743 &self,
744 name: &str,
745 default: Option<fn() -> T>,
746 ) -> ServerResult<(Pos, T)> {
747 self.get_param_value(&self.item.node.arguments, name, default)
748 }
749}
750
751#[derive(Clone, Copy)]
753pub struct SelectionField<'a> {
754 pub(crate) fragments: &'a HashMap<Name, Positioned<FragmentDefinition>>,
755 pub(crate) field: &'a Field,
756 pub(crate) context: &'a Context<'a>,
757}
758
759impl<'a> SelectionField<'a> {
760 #[inline]
762 pub fn name(&self) -> &'a str {
763 self.field.name.node.as_str()
764 }
765
766 #[inline]
768 pub fn alias(&self) -> Option<&'a str> {
769 self.field.alias.as_ref().map(|alias| alias.node.as_str())
770 }
771
772 pub fn directives(&self) -> ServerResult<Vec<ConstDirective>> {
774 let mut directives = Vec::with_capacity(self.field.directives.len());
775
776 for directive in &self.field.directives {
777 let directive = &directive.node;
778
779 let mut arguments = Vec::with_capacity(directive.arguments.len());
780 for (name, value) in &directive.arguments {
781 let pos = name.pos;
782 arguments.push((
783 name.clone(),
784 value.position_node(
785 value
786 .node
787 .clone()
788 .into_const_with(|name| self.context.var_value(&name, pos))?,
789 ),
790 ));
791 }
792
793 directives.push(ConstDirective {
794 name: directive.name.clone(),
795 arguments,
796 });
797 }
798
799 Ok(directives)
800 }
801
802 pub fn arguments(&self) -> ServerResult<Vec<(Name, Value)>> {
804 let mut arguments = Vec::with_capacity(self.field.arguments.len());
805 for (name, value) in &self.field.arguments {
806 let pos = name.pos;
807 arguments.push((
808 name.node.clone(),
809 value
810 .clone()
811 .node
812 .into_const_with(|name| self.context.var_value(&name, pos))?,
813 ));
814 }
815 Ok(arguments)
816 }
817
818 pub fn selection_set(&self) -> impl Iterator<Item = SelectionField<'a>> {
820 SelectionFieldsIter {
821 fragments: self.fragments,
822 iter: vec![self.field.selection_set.node.items.iter()],
823 context: self.context,
824 }
825 }
826}
827
828impl Debug for SelectionField<'_> {
829 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
830 struct DebugSelectionSet<'a>(Vec<SelectionField<'a>>);
831
832 impl Debug for DebugSelectionSet<'_> {
833 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
834 f.debug_list().entries(&self.0).finish()
835 }
836 }
837
838 f.debug_struct(self.name())
839 .field("name", &self.name())
840 .field(
841 "selection_set",
842 &DebugSelectionSet(self.selection_set().collect()),
843 )
844 .finish()
845 }
846}
847
848struct SelectionFieldsIter<'a> {
849 fragments: &'a HashMap<Name, Positioned<FragmentDefinition>>,
850 iter: Vec<std::slice::Iter<'a, Positioned<Selection>>>,
851 context: &'a Context<'a>,
852}
853
854impl<'a> Iterator for SelectionFieldsIter<'a> {
855 type Item = SelectionField<'a>;
856
857 fn next(&mut self) -> Option<Self::Item> {
858 loop {
859 let it = self.iter.last_mut()?;
860 let item = it.next();
861
862 match item {
863 Some(selection) => match &selection.node {
864 Selection::Field(field) => {
865 return Some(SelectionField {
866 fragments: self.fragments,
867 field: &field.node,
868 context: self.context,
869 });
870 }
871 Selection::FragmentSpread(fragment_spread) => {
872 if let Some(fragment) =
873 self.fragments.get(&fragment_spread.node.fragment_name.node)
874 {
875 self.iter
876 .push(fragment.node.selection_set.node.items.iter());
877 }
878 }
879 Selection::InlineFragment(inline_fragment) => {
880 self.iter
881 .push(inline_fragment.node.selection_set.node.items.iter());
882 }
883 },
884 None => {
885 self.iter.pop();
886 }
887 }
888 }
889 }
890}