@@ -229,6 +229,15 @@ class await_async : public coro::suspend_always
229
229
}
230
230
};
231
231
232
+ // Directive order matters, and some of them are repeatable. So rather than passing them in a
233
+ // response::Value, pass directives in something like the underlying response::MapType which
234
+ // preserves the order of the elements without complete uniqueness.
235
+ using Directives = std::vector<std::pair<std::string_view, response::Value>>;
236
+
237
+ // Traversing a fragment spread adds a new set of directives.
238
+ using FragmentDefinitionDirectiveStack = std::list<std::reference_wrapper<const Directives>>;
239
+ using FragmentSpreadDirectiveStack = std::list<Directives>;
240
+
232
241
// Pass a common bundle of parameters to all of the generated Object::getField accessors in a
233
242
// SelectionSet
234
243
struct SelectionSetParams
@@ -239,14 +248,14 @@ struct SelectionSetParams
239
248
// The lifetime of each of these borrowed references is guaranteed until the future returned
240
249
// by the accessor is resolved or destroyed. They are owned by the OperationData shared pointer.
241
250
const std::shared_ptr<RequestState>& state;
242
- const response::Value & operationDirectives;
243
- const response::Value& fragmentDefinitionDirectives;
251
+ const Directives & operationDirectives;
252
+ const std::shared_ptr<FragmentDefinitionDirectiveStack> fragmentDefinitionDirectives;
244
253
245
254
// Fragment directives are shared for all fields in that fragment, but they aren't kept alive
246
255
// after the call to the last accessor in the fragment. If you need to keep them alive longer,
247
- // you'll need to explicitly copy them into other instances of response::Value .
248
- const response::Value& fragmentSpreadDirectives;
249
- const response::Value& inlineFragmentDirectives;
256
+ // you'll need to explicitly copy them into other instances of Directives .
257
+ const std::shared_ptr<FragmentSpreadDirectiveStack> fragmentSpreadDirectives;
258
+ const std::shared_ptr<FragmentSpreadDirectiveStack> inlineFragmentDirectives;
250
259
251
260
// Field error path to this selection set.
252
261
std::optional<field_path> errorPath;
@@ -259,12 +268,12 @@ struct SelectionSetParams
259
268
struct FieldParams : SelectionSetParams
260
269
{
261
270
GRAPHQLSERVICE_EXPORT explicit FieldParams (
262
- SelectionSetParams&& selectionSetParams, response::Value directives);
271
+ SelectionSetParams&& selectionSetParams, Directives directives);
263
272
264
273
// Each field owns its own field-specific directives. Once the accessor returns it will be
265
274
// destroyed, but you can move it into another instance of response::Value to keep it alive
266
275
// longer.
267
- response::Value fieldDirectives;
276
+ Directives fieldDirectives;
268
277
};
269
278
270
279
// Field accessors may return either a result of T, an awaitable of T, or a std::future<T>, so at
@@ -379,11 +388,11 @@ class Fragment
379
388
380
389
std::string_view getType () const ;
381
390
const peg::ast_node& getSelection () const ;
382
- const response::Value & getDirectives () const ;
391
+ const Directives & getDirectives () const ;
383
392
384
393
private:
385
394
std::string_view _type;
386
- response::Value _directives;
395
+ Directives _directives;
387
396
388
397
std::reference_wrapper<const peg::ast_node> _selection;
389
398
};
@@ -399,16 +408,16 @@ struct ResolverParams : SelectionSetParams
399
408
{
400
409
GRAPHQLSERVICE_EXPORT explicit ResolverParams (const SelectionSetParams& selectionSetParams,
401
410
const peg::ast_node& field, std::string&& fieldName, response::Value arguments,
402
- response::Value fieldDirectives, const peg::ast_node* selection,
403
- const FragmentMap& fragments, const response::Value& variables);
411
+ Directives fieldDirectives, const peg::ast_node* selection, const FragmentMap& fragments ,
412
+ const response::Value& variables);
404
413
405
414
GRAPHQLSERVICE_EXPORT schema_location getLocation () const ;
406
415
407
416
// These values are different for each resolver.
408
417
const peg::ast_node& field;
409
418
std::string fieldName;
410
419
response::Value arguments { response::Type::Map };
411
- response::Value fieldDirectives { response::Type::Map } ;
420
+ Directives fieldDirectives;
412
421
const peg::ast_node* selection;
413
422
414
423
// These values remain unchanged for the entire operation, but they're passed to each of the
@@ -944,19 +953,20 @@ struct SubscriptionParams
944
953
struct OperationData : std::enable_shared_from_this<OperationData>
945
954
{
946
955
explicit OperationData (std::shared_ptr<RequestState> state, response::Value variables,
947
- response::Value directives, FragmentMap fragments);
956
+ Directives directives, FragmentMap fragments);
948
957
949
958
std::shared_ptr<RequestState> state;
950
959
response::Value variables;
951
- response::Value directives;
960
+ Directives directives;
952
961
FragmentMap fragments;
953
962
};
954
963
955
964
// Subscription callbacks receive the response::Value representing the result of evaluating the
956
965
// SelectionSet against the payload.
957
966
using SubscriptionCallback = std::function<void (response::Value)>;
958
967
using SubscriptionArguments = std::map<std::string_view, response::Value>;
959
- using SubscriptionFilterCallback = std::function<bool (response::MapType::const_reference)>;
968
+ using SubscriptionArgumentFilterCallback = std::function<bool (response::MapType::const_reference)>;
969
+ using SubscriptionDirectiveFilterCallback = std::function<bool (Directives::const_reference)>;
960
970
961
971
// Subscriptions are stored in maps using these keys.
962
972
using SubscriptionKey = size_t ;
@@ -970,15 +980,15 @@ using AwaitableDeliver = internal::Awaitable<void>;
970
980
struct SubscriptionData : std::enable_shared_from_this<SubscriptionData>
971
981
{
972
982
explicit SubscriptionData (std::shared_ptr<OperationData> data, SubscriptionName&& field,
973
- response::Value arguments, response::Value fieldDirectives, peg::ast&& query,
983
+ response::Value arguments, Directives fieldDirectives, peg::ast&& query,
974
984
std::string&& operationName, SubscriptionCallback&& callback,
975
985
const peg::ast_node& selection);
976
986
977
987
std::shared_ptr<OperationData> data;
978
988
979
989
SubscriptionName field;
980
990
response::Value arguments;
981
- response::Value fieldDirectives;
991
+ Directives fieldDirectives;
982
992
peg::ast query;
983
993
std::string operationName;
984
994
SubscriptionCallback callback;
@@ -1023,29 +1033,29 @@ class Request : public std::enable_shared_from_this<Request>
1023
1033
GRAPHQLSERVICE_EXPORT void deliver (const SubscriptionName& name,
1024
1034
const SubscriptionArguments& arguments, std::shared_ptr<Object> subscriptionObject) const ;
1025
1035
GRAPHQLSERVICE_EXPORT void deliver (const SubscriptionName& name,
1026
- const SubscriptionArguments& arguments, const SubscriptionArguments & directives,
1036
+ const SubscriptionArguments& arguments, const Directives & directives,
1027
1037
std::shared_ptr<Object> subscriptionObject) const ;
1028
1038
GRAPHQLSERVICE_EXPORT void deliver (const SubscriptionName& name,
1029
- const SubscriptionFilterCallback & applyArguments,
1039
+ const SubscriptionArgumentFilterCallback & applyArguments,
1030
1040
std::shared_ptr<Object> subscriptionObject) const ;
1031
1041
GRAPHQLSERVICE_EXPORT void deliver (const SubscriptionName& name,
1032
- const SubscriptionFilterCallback & applyArguments,
1033
- const SubscriptionFilterCallback & applyDirectives,
1042
+ const SubscriptionArgumentFilterCallback & applyArguments,
1043
+ const SubscriptionDirectiveFilterCallback & applyDirectives,
1034
1044
std::shared_ptr<Object> subscriptionObject) const ;
1035
1045
1036
1046
GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
1037
1047
std::shared_ptr<Object> subscriptionObject) const ;
1038
1048
GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
1039
1049
const SubscriptionArguments& arguments, std::shared_ptr<Object> subscriptionObject) const ;
1040
1050
GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
1041
- const SubscriptionArguments& arguments, const SubscriptionArguments & directives,
1051
+ const SubscriptionArguments& arguments, const Directives & directives,
1042
1052
std::shared_ptr<Object> subscriptionObject) const ;
1043
1053
GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
1044
- const SubscriptionFilterCallback & applyArguments,
1054
+ const SubscriptionArgumentFilterCallback & applyArguments,
1045
1055
std::shared_ptr<Object> subscriptionObject) const ;
1046
1056
GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
1047
- const SubscriptionFilterCallback & applyArguments,
1048
- const SubscriptionFilterCallback & applyDirectives,
1057
+ const SubscriptionArgumentFilterCallback & applyArguments,
1058
+ const SubscriptionDirectiveFilterCallback & applyDirectives,
1049
1059
std::shared_ptr<Object> subscriptionObject) const ;
1050
1060
1051
1061
private:
0 commit comments