juniper/executor/
owned_executor.rs

1use std::{
2    collections::HashMap,
3    sync::{Arc, RwLock},
4};
5
6use crate::{
7    ExecutionError, Executor, Selection, Variables,
8    ast::Fragment,
9    executor::FieldPath,
10    parser::SourcePosition,
11    schema::model::{SchemaType, TypeType},
12};
13
14/// [`Executor`] owning all its variables. Can be used after [`Executor`] was
15/// destroyed.
16pub struct OwnedExecutor<'a, CtxT, S> {
17    pub(super) fragments: HashMap<&'a str, Fragment<'a, S>>,
18    pub(super) variables: Variables<S>,
19    pub(super) current_selection_set: Option<Vec<Selection<'a, S>>>,
20    pub(super) parent_selection_set: Option<Vec<Selection<'a, S>>>,
21    pub(super) current_type: TypeType<'a, S>,
22    pub(super) schema: &'a SchemaType<S>,
23    pub(super) context: &'a CtxT,
24    pub(super) errors: RwLock<Vec<ExecutionError<S>>>,
25    pub(super) field_path: Arc<FieldPath<'a>>,
26}
27
28impl<CtxT, S> Clone for OwnedExecutor<'_, CtxT, S>
29where
30    S: Clone,
31{
32    fn clone(&self) -> Self {
33        Self {
34            fragments: self.fragments.clone(),
35            variables: self.variables.clone(),
36            current_selection_set: self.current_selection_set.clone(),
37            parent_selection_set: self.parent_selection_set.clone(),
38            current_type: self.current_type.clone(),
39            schema: self.schema,
40            context: self.context,
41            errors: RwLock::new(vec![]),
42            field_path: self.field_path.clone(),
43        }
44    }
45}
46
47impl<'a, CtxT, S> OwnedExecutor<'a, CtxT, S>
48where
49    S: Clone,
50{
51    #[doc(hidden)]
52    #[must_use]
53    pub fn type_sub_executor(
54        &self,
55        type_name: Option<&str>,
56        selection_set: Option<Vec<Selection<'a, S>>>,
57    ) -> OwnedExecutor<'a, CtxT, S> {
58        OwnedExecutor {
59            fragments: self.fragments.clone(),
60            variables: self.variables.clone(),
61            current_selection_set: selection_set,
62            parent_selection_set: self.current_selection_set.clone(),
63            current_type: match type_name {
64                Some(type_name) => self.schema.type_by_name(type_name).expect("Type not found"),
65                None => self.current_type.clone(),
66            },
67            schema: self.schema,
68            context: self.context,
69            errors: RwLock::new(vec![]),
70            field_path: self.field_path.clone(),
71        }
72    }
73
74    #[doc(hidden)]
75    pub fn variables(&self) -> Variables<S> {
76        self.variables.clone()
77    }
78
79    #[doc(hidden)]
80    #[must_use]
81    pub fn field_sub_executor(
82        &self,
83        field_alias: &'a str,
84        field_name: &'a str,
85        location: SourcePosition,
86        selection_set: Option<Vec<Selection<'a, S>>>,
87    ) -> OwnedExecutor<'a, CtxT, S> {
88        OwnedExecutor {
89            fragments: self.fragments.clone(),
90            variables: self.variables.clone(),
91            current_selection_set: selection_set,
92            parent_selection_set: self.current_selection_set.clone(),
93            current_type: self.schema.make_type(
94                &self
95                    .current_type
96                    .innermost_concrete()
97                    .field_by_name(field_name)
98                    .expect("Field not found on inner type")
99                    .field_type,
100            ),
101            schema: self.schema,
102            context: self.context,
103            errors: RwLock::new(vec![]),
104            field_path: Arc::new(FieldPath::Field(
105                field_alias,
106                location,
107                Arc::clone(&self.field_path),
108            )),
109        }
110    }
111
112    #[doc(hidden)]
113    pub fn as_executor(&self) -> Executor<'_, '_, CtxT, S> {
114        Executor {
115            fragments: &self.fragments,
116            variables: &self.variables,
117            current_selection_set: self.current_selection_set.as_deref(),
118            parent_selection_set: self.parent_selection_set.as_deref(),
119            current_type: self.current_type.clone(),
120            schema: self.schema,
121            context: self.context,
122            errors: &self.errors,
123            field_path: Arc::clone(&self.field_path),
124        }
125    }
126}
127
128impl<'a, CtxT, S> OwnedExecutor<'a, CtxT, S> {
129    #[doc(hidden)]
130    pub fn fragment_by_name<'b>(&'b self, name: &str) -> Option<&'b Fragment<'a, S>> {
131        self.fragments.get(name)
132    }
133
134    #[doc(hidden)]
135    pub fn context(&self) -> &'a CtxT {
136        self.context
137    }
138
139    #[doc(hidden)]
140    pub fn schema(&self) -> &'a SchemaType<S> {
141        self.schema
142    }
143
144    #[doc(hidden)]
145    pub fn location(&self) -> &SourcePosition {
146        self.field_path.location()
147    }
148}