Skip to content

Commit 11d7d0c

Browse files
committed
feat: add ResolverResult::visit and visitErrorValues
1 parent e85fc7e commit 11d7d0c

File tree

3 files changed

+74
-38
lines changed

3 files changed

+74
-38
lines changed

include/graphqlservice/GraphQLService.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ struct [[nodiscard("unnecessary construction")]] schema_error
7373
[[nodiscard("unnecessary memory copy")]] GRAPHQLSERVICE_EXPORT response::Value buildErrorValues(
7474
std::list<schema_error>&& structuredErrors);
7575

76+
[[nodiscard("unnecessary memory copy")]] GRAPHQLSERVICE_EXPORT response::ValueTokenStream
77+
visitErrorValues(std::list<schema_error>&& structuredErrors);
78+
7679
// This exception bubbles up 1 or more error messages to the JSON results.
7780
class [[nodiscard("unnecessary construction")]] schema_exception : public std::exception
7881
{
@@ -540,6 +543,7 @@ struct [[nodiscard("unnecessary construction")]] ResolverParams : SelectionSetPa
540543
struct [[nodiscard("unnecessary construction")]] ResolverResult
541544
{
542545
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::Value document() &&;
546+
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::ValueTokenStream visit() &&;
543547

544548
response::ValueTokenStream data {};
545549
std::list<schema_error> errors {};

include/graphqlservice/Service.ixx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ using service::buildErrorPath;
3333

3434
using service::schema_error;
3535
using service::buildErrorValues;
36+
using service::visitErrorValues;
3637

3738
using service::schema_exception;
3839
using service::unimplemented_method;

src/GraphQLService.cpp

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,59 +17,73 @@ using namespace std::literals;
1717

1818
namespace graphql::service {
1919

20-
void addErrorMessage(std::string&& message, response::Value& error)
20+
response::ValueTokenStream addErrorMessage(std::string&& message)
2121
{
22-
error.emplace_back(std::string { strMessage }, response::Value(std::move(message)));
22+
response::ValueTokenStream result {};
23+
24+
result.push_back(response::ValueToken::AddMember { std::string { strMessage } });
25+
result.push_back(response::ValueToken::StringValue { std::move(message) });
26+
27+
return result;
2328
}
2429

25-
void addErrorLocation(const schema_location& location, response::Value& error)
30+
response::ValueTokenStream addErrorLocation(const schema_location& location)
2631
{
32+
response::ValueTokenStream result {};
33+
2734
if (location.line == 0)
2835
{
29-
return;
36+
return result;
3037
}
3138

32-
response::Value errorLocation(response::Type::Map);
39+
result.push_back(response::ValueToken::AddMember { std::string { strLocations } });
3340

34-
errorLocation.reserve(2);
35-
errorLocation.emplace_back(std::string { strLine },
36-
response::Value(static_cast<int>(location.line)));
37-
errorLocation.emplace_back(std::string { strColumn },
38-
response::Value(static_cast<int>(location.column)));
41+
result.push_back(response::ValueToken::StartArray {});
42+
result.push_back(response::ValueToken::Reserve { 1 });
43+
result.push_back(response::ValueToken::StartObject {});
44+
result.push_back(response::ValueToken::Reserve { 2 });
3945

40-
response::Value errorLocations(response::Type::List);
46+
result.push_back(response::ValueToken::AddMember { std::string { strLine } });
47+
result.push_back(response::ValueToken::IntValue { static_cast<int>(location.line) });
48+
result.push_back(response::ValueToken::AddMember { std::string { strColumn } });
49+
result.push_back(response::ValueToken::IntValue { static_cast<int>(location.column) });
4150

42-
errorLocations.reserve(1);
43-
errorLocations.emplace_back(std::move(errorLocation));
51+
result.push_back(response::ValueToken::EndObject {});
52+
result.push_back(response::ValueToken::EndArray {});
4453

45-
error.emplace_back(std::string { strLocations }, std::move(errorLocations));
54+
return result;
4655
}
4756

48-
void addErrorPath(const error_path& path, response::Value& error)
57+
response::ValueTokenStream addErrorPath(const error_path& path)
4958
{
59+
response::ValueTokenStream result {};
60+
5061
if (path.empty())
5162
{
52-
return;
63+
return result;
5364
}
5465

55-
response::Value errorPath(response::Type::List);
66+
result.push_back(response::ValueToken::AddMember { std::string { strPath } });
67+
result.push_back(response::ValueToken::StartArray {});
68+
result.push_back(response::ValueToken::Reserve { path.size() });
5669

57-
errorPath.reserve(path.size());
5870
for (const auto& segment : path)
5971
{
6072
if (std::holds_alternative<std::string_view>(segment))
6173
{
62-
errorPath.emplace_back(
63-
response::Value { std::string { std::get<std::string_view>(segment) } });
74+
result.push_back(response::ValueToken::StringValue {
75+
std::string { std::get<std::string_view>(segment) } });
6476
}
6577
else if (std::holds_alternative<std::size_t>(segment))
6678
{
67-
errorPath.emplace_back(
68-
response::Value(static_cast<int>(std::get<std::size_t>(segment))));
79+
result.push_back(response::ValueToken::IntValue {
80+
static_cast<int>(std::get<std::size_t>(segment)) });
6981
}
7082
}
7183

72-
error.emplace_back(std::string { strPath }, std::move(errorPath));
84+
result.push_back(response::ValueToken::EndArray {});
85+
86+
return result;
7387
}
7488

7589
error_path buildErrorPath(const std::optional<field_path>& path)
@@ -99,22 +113,30 @@ error_path buildErrorPath(const std::optional<field_path>& path)
99113

100114
response::Value buildErrorValues(std::list<schema_error>&& structuredErrors)
101115
{
102-
response::Value errors(response::Type::List);
116+
return visitErrorValues(std::move(structuredErrors)).value();
117+
}
118+
119+
response::ValueTokenStream visitErrorValues(std::list<schema_error>&& structuredErrors)
120+
{
121+
response::ValueTokenStream errors;
103122

104-
errors.reserve(structuredErrors.size());
123+
errors.push_back(response::ValueToken::StartArray {});
124+
errors.push_back(response::ValueToken::Reserve { structuredErrors.size() });
105125

106126
for (auto& error : structuredErrors)
107127
{
108-
response::Value entry(response::Type::Map);
128+
errors.push_back(response::ValueToken::StartObject {});
129+
errors.push_back(response::ValueToken::Reserve { 3 });
109130

110-
entry.reserve(3);
111-
addErrorMessage(std::move(error.message), entry);
112-
addErrorLocation(error.location, entry);
113-
addErrorPath(error.path, entry);
131+
errors.append(addErrorMessage(std::move(error.message)));
132+
errors.append(addErrorLocation(error.location));
133+
errors.append(addErrorPath(error.path));
114134

115-
errors.emplace_back(std::move(entry));
135+
errors.push_back(response::ValueToken::EndObject {});
116136
}
117137

138+
errors.push_back(response::ValueToken::EndArray {});
139+
118140
return errors;
119141
}
120142

@@ -245,17 +267,17 @@ void await_worker_queue::resumePending()
245267
// Default to immediate synchronous execution.
246268
await_async::await_async()
247269
: _pimpl { std::static_pointer_cast<const Concept>(
248-
std::make_shared<Model<std::suspend_never>>(std::make_shared<std::suspend_never>())) }
270+
std::make_shared<Model<std::suspend_never>>(std::make_shared<std::suspend_never>())) }
249271
{
250272
}
251273

252274
// Implicitly convert a std::launch parameter used with std::async to an awaitable.
253275
await_async::await_async(std::launch launch)
254276
: _pimpl { ((launch & std::launch::async) == std::launch::async)
255277
? std::static_pointer_cast<const Concept>(std::make_shared<Model<await_worker_thread>>(
256-
std::make_shared<await_worker_thread>()))
278+
std::make_shared<await_worker_thread>()))
257279
: std::static_pointer_cast<const Concept>(std::make_shared<Model<std::suspend_never>>(
258-
std::make_shared<std::suspend_never>())) }
280+
std::make_shared<std::suspend_never>())) }
259281
{
260282
}
261283

@@ -623,16 +645,25 @@ schema_location ResolverParams::getLocation() const
623645

624646
response::Value ResolverResult::document() &&
625647
{
626-
response::Value document { response::Type::Map };
648+
return std::move(*this).visit().value();
649+
}
627650

628-
document.emplace_back(std::string { strData }, std::move(data).value());
651+
response::ValueTokenStream ResolverResult::visit() &&
652+
{
653+
response::ValueTokenStream result { response::ValueToken::StartObject {} };
654+
655+
result.push_back(response::ValueToken::AddMember { std::string { strData } });
656+
result.append(std::move(data));
629657

630658
if (!errors.empty())
631659
{
632-
document.emplace_back(std::string { strErrors }, buildErrorValues(std::move(errors)));
660+
result.push_back(response::ValueToken::AddMember { std::string { strErrors } });
661+
result.append(visitErrorValues(std::move(errors)));
633662
}
634663

635-
return document;
664+
result.push_back(response::ValueToken::EndObject {});
665+
666+
return result;
636667
}
637668

638669
template <>

0 commit comments

Comments
 (0)