@@ -349,6 +349,11 @@ void ResolverVisitor::add_error(schema_error&& error)
349349 _concept->add_error (std::move (error));
350350}
351351
352+ void ResolverVisitor::complete ()
353+ {
354+ _concept->complete ();
355+ }
356+
352357FieldParams::FieldParams (SelectionSetParams&& selectionSetParams, Directives directives)
353358 : SelectionSetParams(std::move(selectionSetParams))
354359 , fieldDirectives(std::move(directives))
@@ -852,6 +857,7 @@ class ResolverResultVisitor
852857 void add_int (int value);
853858 void add_float (double value);
854859 void add_error (schema_error&& error);
860+ void complete ();
855861
856862 response::Value document ();
857863
@@ -952,6 +958,10 @@ void ResolverResultVisitor::add_error(schema_error&& error)
952958 _errors.push_back (std::move (error));
953959}
954960
961+ void ResolverResultVisitor::complete ()
962+ {
963+ }
964+
955965response::Value ResolverResultVisitor::document ()
956966{
957967 response::Value document { response::Type::Map };
@@ -991,15 +1001,6 @@ void ResolverResultVisitor::add_value(response::Value&& value)
9911001 }
9921002}
9931003
994- response::Value ResolverResult::toValue () &&
995- {
996- auto visitor = std::make_shared<ResolverResultVisitor>();
997-
998- (std::move (*this )).visit (std::make_shared<ResolverVisitor>(visitor));
999-
1000- return visitor->document ();
1001- }
1002-
10031004void ResolverResult::visit (const std::shared_ptr<ResolverVisitor>& visitor) &&
10041005{
10051006 for (auto & token : data)
@@ -1011,6 +1012,8 @@ void ResolverResult::visit(const std::shared_ptr<ResolverVisitor>& visitor) &&
10111012 {
10121013 visitor->add_error (std::move (error));
10131014 }
1015+
1016+ visitor->complete ();
10141017}
10151018
10161019template <>
@@ -1857,7 +1860,8 @@ void OperationDefinitionVisitor::visit(
18571860
18581861SubscriptionData::SubscriptionData (std::shared_ptr<OperationData> data, SubscriptionName&& field,
18591862 response::Value arguments, Directives fieldDirectives, peg::ast&& query,
1860- std::string&& operationName, SubscriptionCallback&& callback, const peg::ast_node& selection)
1863+ std::string&& operationName, SubscriptionCallbackOrVisitor&& callback,
1864+ const peg::ast_node& selection)
18611865 : data(std::move(data))
18621866 , field(std::move(field))
18631867 , arguments(std::move(arguments))
@@ -2154,6 +2158,15 @@ std::pair<std::string_view, const peg::ast_node*> Request::findOperationDefiniti
21542158}
21552159
21562160response::AwaitableValue Request::resolve (RequestResolveParams params) const
2161+ {
2162+ auto visitor = std::make_shared<ResolverResultVisitor>();
2163+
2164+ co_await visit (std::move (params), std::make_shared<ResolverVisitor>(visitor));
2165+ co_return visitor->document ();
2166+ }
2167+
2168+ AwaitableVisit Request::visit (
2169+ RequestResolveParams params, const std::shared_ptr<ResolverVisitor>& resolverVisitor) const
21572170{
21582171 try
21592172 {
@@ -2210,16 +2223,13 @@ response::AwaitableValue Request::resolve(RequestResolveParams params) const
22102223 co_await params.launch ;
22112224 operationVisitor.visit (operationType, *operationDefinition);
22122225
2213- co_return (co_await operationVisitor.getValue ()).toValue ( );
2226+ (co_await operationVisitor.getValue ()).visit (resolverVisitor );
22142227 }
22152228 catch (schema_exception& ex)
22162229 {
2217- response::Value document (response::Type::Map) ;
2230+ ResolverResult document { {}, ex. getStructuredErrors () } ;
22182231
2219- document.emplace_back (std::string { strData }, response::Value ());
2220- document.emplace_back (std::string { strErrors }, ex.getErrors ());
2221-
2222- co_return std::move (document);
2232+ std::move (document).visit (resolverVisitor);
22232233 }
22242234}
22252235
@@ -2380,26 +2390,42 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const
23802390 params.launch ,
23812391 };
23822392
2383- response::Value document { response::Type::Map };
2393+ ResolverResult document {};
23842394
23852395 try
23862396 {
23872397 co_await params.launch ;
23882398
2389- auto result = co_await optionalOrDefaultSubscription->resolve (selectionSetParams,
2399+ document = co_await optionalOrDefaultSubscription->resolve (selectionSetParams,
23902400 registration->selection ,
23912401 registration->data ->fragments ,
23922402 registration->data ->variables );
2393-
2394- document = std::move (result).toValue ();
23952403 }
23962404 catch (schema_exception& ex)
23972405 {
2398- document.emplace_back (std::string { strData }, response::Value ());
2399- document.emplace_back (std::string { strErrors }, ex.getErrors ());
2406+ document.errors .splice (document.errors .end (), ex.getStructuredErrors ());
24002407 }
24012408
2402- registration->callback (std::move (document));
2409+ std::visit (
2410+ [result = std::move (document)](const auto & callback) mutable {
2411+ using callback_type = std::decay_t <decltype (callback)>;
2412+
2413+ if constexpr (std::is_same_v<callback_type, SubscriptionCallback>)
2414+ {
2415+ auto visitor = std::make_shared<ResolverResultVisitor>();
2416+
2417+ (std::move (result)).visit (std::make_shared<ResolverVisitor>(visitor));
2418+
2419+ callback (visitor->document ());
2420+ }
2421+ else if constexpr (std::is_same_v<callback_type, SubscriptionVisitor>)
2422+ {
2423+ auto visitor = callback ();
2424+
2425+ (std::move (result)).visit (visitor);
2426+ }
2427+ },
2428+ registration->callback );
24032429 }
24042430
24052431 co_return ;
0 commit comments