@@ -1530,12 +1530,14 @@ void OperationDefinitionVisitor::visit(const std::string& operationType, const p
15301530 }, std::cref (*operationDefinition.children .back ()));
15311531}
15321532
1533- SubscriptionData::SubscriptionData (std::shared_ptr<OperationData>&& data, SubscriptionName&& field, response::Value&& arguments,
1533+ SubscriptionData::SubscriptionData (std::shared_ptr<OperationData>&& data, SubscriptionName&& field,
1534+ response::Value&& arguments, response::Value&& fieldDirectives,
15341535 peg::ast&& query, std::string&& operationName, SubscriptionCallback&& callback,
15351536 const peg::ast_node& selection)
15361537 : data(std::move(data))
15371538 , field(std::move(field))
15381539 , arguments(std::move(arguments))
1540+ , fieldDirectives(std::move(fieldDirectives))
15391541 , query(std::move(query))
15401542 , operationName(std::move(operationName))
15411543 , callback(std::move(callback))
@@ -1566,6 +1568,7 @@ class SubscriptionDefinitionVisitor
15661568 const std::shared_ptr<Object>& _subscriptionObject;
15671569 SubscriptionName _field;
15681570 response::Value _arguments;
1571+ response::Value _fieldDirectives;
15691572 std::shared_ptr<SubscriptionData> _result;
15701573};
15711574
@@ -1630,6 +1633,7 @@ void SubscriptionDefinitionVisitor::visit(const peg::ast_node& operationDefiniti
16301633 std::move (_fragments)),
16311634 std::move (_field),
16321635 std::move (_arguments),
1636+ std::move (_fieldDirectives),
16331637 std::move (_params.query ),
16341638 std::move (_params.operationName ),
16351639 std::move (_callback),
@@ -1670,6 +1674,8 @@ void SubscriptionDefinitionVisitor::visitField(const peg::ast_node& field)
16701674 return ;
16711675 }
16721676
1677+ _fieldDirectives = directiveVisitor.getDirectives ();
1678+
16731679 response::Value arguments (response::Type::Map);
16741680
16751681 peg::on_first_child<peg::arguments>(field,
@@ -2176,35 +2182,76 @@ void Request::deliver(const SubscriptionName& name, const std::shared_ptr<Object
21762182 deliver (std::launch::deferred, name, subscriptionObject);
21772183}
21782184
2179- void Request::deliver (std::launch launch , const SubscriptionName& name , const std::shared_ptr<Object>& subscriptionObject) const
2185+ void Request::deliver (const SubscriptionName& name , const SubscriptionArguments& arguments , const std::shared_ptr<Object>& subscriptionObject) const
21802186{
2181- deliver (launch, name, SubscriptionArguments {} , subscriptionObject);
2187+ deliver (std:: launch::deferred , name, arguments , subscriptionObject);
21822188}
21832189
2184- void Request::deliver (const SubscriptionName& name, const SubscriptionArguments& arguments, const std::shared_ptr<Object>& subscriptionObject) const
2190+ void Request::deliver (const SubscriptionName& name, const SubscriptionArguments& arguments,
2191+ const SubscriptionArguments& directives, const std::shared_ptr<Object>& subscriptionObject) const
21852192{
2186- deliver (std::launch::deferred, name, arguments, subscriptionObject);
2193+ deliver (std::launch::deferred, name, arguments, directives, subscriptionObject);
2194+ }
2195+
2196+ void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments,
2197+ const std::shared_ptr<Object>& subscriptionObject) const
2198+ {
2199+ deliver (std::launch::deferred, name, applyArguments, subscriptionObject);
2200+ }
2201+
2202+ void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments,
2203+ const SubscriptionFilterCallback& applyDirectives, const std::shared_ptr<Object>& subscriptionObject) const
2204+ {
2205+ deliver (std::launch::deferred, name, applyArguments, applyDirectives, subscriptionObject);
2206+ }
2207+
2208+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2209+ const std::shared_ptr<Object>& subscriptionObject) const
2210+ {
2211+ deliver (launch, name, SubscriptionArguments {}, SubscriptionArguments {}, subscriptionObject);
21872212}
21882213
21892214void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionArguments& arguments, const std::shared_ptr<Object>& subscriptionObject) const
21902215{
2191- SubscriptionFilterCallback exactMatch = [&arguments](response::MapType::const_reference required) noexcept -> bool
2192- {
2216+ deliver (launch, name, arguments, SubscriptionArguments {}, subscriptionObject);
2217+ }
2218+
2219+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2220+ const SubscriptionArguments& arguments, const SubscriptionArguments& directives,
2221+ const std::shared_ptr<Object>& subscriptionObject) const
2222+ {
2223+ SubscriptionFilterCallback argumentsMatch =
2224+ [&arguments](response::MapType::const_reference required) noexcept -> bool {
21932225 auto itrArgument = arguments.find (required.first );
21942226
2195- return (itrArgument != arguments.cend ()
2196- && itrArgument->second == required.second );
2227+ return (itrArgument != arguments.cend () && itrArgument->second == required.second );
21972228 };
21982229
2199- deliver (launch, name, exactMatch, subscriptionObject);
2230+ SubscriptionFilterCallback directivesMatch =
2231+ [&directives](response::MapType::const_reference required) noexcept -> bool {
2232+ auto itrDirective = directives.find (required.first );
2233+
2234+ return (itrDirective != directives.cend () && itrDirective->second == required.second );
2235+ };
2236+
2237+ deliver (launch, name, argumentsMatch, directivesMatch, subscriptionObject);
22002238}
22012239
2202- void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& apply , const std::shared_ptr<Object>& subscriptionObject) const
2240+ void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments , const std::shared_ptr<Object>& subscriptionObject) const
22032241{
2204- deliver (std::launch::deferred, name, apply, subscriptionObject);
2242+ deliver (
2243+ launch,
2244+ name,
2245+ applyArguments,
2246+ [](response::MapType::const_reference) noexcept {
2247+ return true ;
2248+ },
2249+ subscriptionObject);
22052250}
22062251
2207- void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionFilterCallback& apply, const std::shared_ptr<Object>& subscriptionObject) const
2252+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2253+ const SubscriptionFilterCallback& applyArguments, const SubscriptionFilterCallback& applyDirectives,
2254+ const std::shared_ptr<Object>& subscriptionObject) const
22082255{
22092256 const auto & optionalOrDefaultSubscription = subscriptionObject
22102257 ? subscriptionObject
@@ -2230,7 +2277,7 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
22302277 // in this event, don't deliver the event to this subscription
22312278 for (const auto & required : subscriptionArguments)
22322279 {
2233- if (!apply (required))
2280+ if (!applyArguments (required))
22342281 {
22352282 matchedArguments = false ;
22362283 break ;
@@ -2242,6 +2289,25 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
22422289 continue ;
22432290 }
22442291
2292+ // If the field in this subscription had field directives that did not match what was
2293+ // provided in this event, don't deliver the event to this subscription
2294+ const auto & subscriptionFieldDirectives = registration->fieldDirectives ;
2295+ bool matchedFieldDirectives = true ;
2296+
2297+ for (const auto & required : subscriptionFieldDirectives)
2298+ {
2299+ if (!applyDirectives (required))
2300+ {
2301+ matchedFieldDirectives = false ;
2302+ break ;
2303+ }
2304+ }
2305+
2306+ if (!matchedFieldDirectives)
2307+ {
2308+ continue ;
2309+ }
2310+
22452311 std::future<response::Value> result;
22462312 response::Value emptyFragmentDirectives (response::Type::Map);
22472313 const SelectionSetParams selectionSetParams {
@@ -2257,13 +2323,17 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
22572323
22582324 try
22592325 {
2260- result = std::async (launch,
2261- [registration](std::future<response::Value> document)
2262- {
2263- return document.get ();
2264- }, optionalOrDefaultSubscription->resolve (selectionSetParams, registration->selection , registration->data ->fragments , registration->data ->variables ));
2326+ result = std::async (
2327+ launch,
2328+ [registration](std::future<response::Value> document) {
2329+ return document.get ();
2330+ },
2331+ optionalOrDefaultSubscription->resolve (selectionSetParams,
2332+ registration->selection ,
2333+ registration->data ->fragments ,
2334+ registration->data ->variables ));
22652335 }
2266- catch (schema_exception & ex)
2336+ catch (schema_exception& ex)
22672337 {
22682338 std::promise<response::Value> promise;
22692339 response::Value document (response::Type::Map);
@@ -2275,11 +2345,12 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
22752345 result = promise.get_future ();
22762346 }
22772347
2278- callbacks.push (std::async (launch,
2279- [registration](std::future<response::Value> document)
2280- {
2281- registration->callback (std::move (document));
2282- }, std::move (result)));
2348+ callbacks.push (std::async (
2349+ launch,
2350+ [registration](std::future<response::Value> document) {
2351+ registration->callback (std::move (document));
2352+ },
2353+ std::move (result)));
22832354 }
22842355
22852356 while (!callbacks.empty ())
0 commit comments