1
1
use std:: collections:: HashMap ;
2
2
use std:: marker:: PhantomData ;
3
+ use std:: sync:: RwLock ;
3
4
4
5
use :: GraphQLError ;
5
6
use ast:: { InputValue , ToInputValue , Document , Selection , Fragment , Definition , Type , FromInputValue , OperationType } ;
@@ -41,7 +42,7 @@ pub struct Executor<'a, CtxT> where CtxT: 'a {
41
42
current_selection_set : Option < Vec < Selection > > ,
42
43
schema : & ' a SchemaType ,
43
44
context : & ' a CtxT ,
44
- errors : & ' a mut Vec < ExecutionError > ,
45
+ errors : & ' a RwLock < Vec < ExecutionError > > ,
45
46
field_path : FieldPath < ' a > ,
46
47
}
47
48
@@ -81,7 +82,7 @@ impl<T> IntoFieldResult<T> for FieldResult<T> {
81
82
82
83
impl < ' a , CtxT > Executor < ' a , CtxT > {
83
84
/// Resolve a single arbitrary value into an `ExecutionResult`
84
- pub fn resolve < T : GraphQLType < CtxT > > ( & mut self , value : & T ) -> ExecutionResult {
85
+ pub fn resolve < T : GraphQLType < CtxT > > ( & self , value : & T ) -> ExecutionResult {
85
86
Ok ( value. resolve (
86
87
match self . current_selection_set {
87
88
Some ( ref sel) => Some ( sel. clone ( ) ) ,
@@ -93,7 +94,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
93
94
/// Resolve a single arbitrary value into a return value
94
95
///
95
96
/// If the field fails to resolve, `null` will be returned.
96
- pub fn resolve_into_value < T : GraphQLType < CtxT > > ( & mut self , value : & T ) -> Value {
97
+ pub fn resolve_into_value < T : GraphQLType < CtxT > > ( & self , value : & T ) -> Value {
97
98
match self . resolve ( value) {
98
99
Ok ( v) => v,
99
100
Err ( e) => {
@@ -108,7 +109,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
108
109
///
109
110
/// This can be used to connect different types, e.g. from different Rust
110
111
/// libraries, that require different context types.
111
- pub fn replaced_context < ' b , NewCtxT > ( & ' b mut self , ctx : & ' b NewCtxT ) -> Executor < ' b , NewCtxT > {
112
+ pub fn replaced_context < ' b , NewCtxT > ( & ' b self , ctx : & ' b NewCtxT ) -> Executor < ' b , NewCtxT > {
112
113
Executor {
113
114
fragments : self . fragments ,
114
115
variables : self . variables ,
@@ -122,7 +123,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
122
123
123
124
#[ doc( hidden) ]
124
125
pub fn sub_executor (
125
- & mut self ,
126
+ & self ,
126
127
field_name : Option < String > ,
127
128
location : SourcePosition ,
128
129
selection_set : Option < Vec < Selection > > ,
@@ -167,11 +168,13 @@ impl<'a, CtxT> Executor<'a, CtxT> {
167
168
}
168
169
169
170
/// Add an error to the execution engine
170
- pub fn push_error ( & mut self , error : String , location : SourcePosition ) {
171
+ pub fn push_error ( & self , error : String , location : SourcePosition ) {
171
172
let mut path = Vec :: new ( ) ;
172
173
self . field_path . construct_path ( & mut path) ;
173
174
174
- self . errors . push ( ExecutionError {
175
+ let mut errors = self . errors . write ( ) . unwrap ( ) ;
176
+
177
+ errors. push ( ExecutionError {
175
178
location : location,
176
179
path : path,
177
180
message : error,
@@ -261,17 +264,17 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
261
264
None => return Err ( GraphQLError :: UnknownOperationName ) ,
262
265
} ;
263
266
264
- let mut errors = Vec :: new ( ) ;
267
+ let errors = RwLock :: new ( Vec :: new ( ) ) ;
265
268
let value;
266
269
267
270
{
268
- let mut executor = Executor {
271
+ let executor = Executor {
269
272
fragments : & fragments. into_iter ( ) . map ( |f| ( f. item . name . item . clone ( ) , f. item ) ) . collect ( ) ,
270
273
variables : variables,
271
274
current_selection_set : Some ( op. item . selection_set ) ,
272
275
schema : & root_node. schema ,
273
276
context : context,
274
- errors : & mut errors,
277
+ errors : & errors,
275
278
field_path : FieldPath :: Root ( op. start ) ,
276
279
} ;
277
280
@@ -281,6 +284,7 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
281
284
} ;
282
285
}
283
286
287
+ let mut errors = errors. into_inner ( ) . unwrap ( ) ;
284
288
errors. sort ( ) ;
285
289
286
290
Ok ( ( value, errors) )
0 commit comments