Skip to content

Commit 817c183

Browse files
committed
Deduplicate ModifiedVariable and ModifiedResponse
1 parent c09ecbd commit 817c183

File tree

4 files changed

+240
-8
lines changed

4 files changed

+240
-8
lines changed

samples/client/multiple/MultipleQueriesClient.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ const std::string& GetRequestText() noexcept
8888
# Try a field with a C++ keyword
8989
default
9090
}
91+
92+
mutation CompleteTaskMutation($input: CompleteTaskInput = {id: "ZmFrZVRhc2tJZA==", isComplete: true, clientMutationId: "Hi There!"}, $skipClientMutationId: Boolean!) {
93+
completedTask: completeTask(input: $input) {
94+
completedTask: task {
95+
completedTaskId: id
96+
title
97+
isComplete
98+
}
99+
clientMutationId @skip(if: $skipClientMutationId)
100+
}
101+
}
91102
)gql"s;
92103

93104
return s_request;
@@ -573,4 +584,134 @@ Response parseResponse(response::Value&& response)
573584
}
574585

575586
} // namespace query::Miscellaneous
587+
588+
template <>
589+
constexpr bool isInputType<CompleteTaskInput>() noexcept
590+
{
591+
return true;
592+
}
593+
594+
template <>
595+
response::Value ModifiedVariable<TaskState>::serialize(TaskState&& value)
596+
{
597+
response::Value result { response::Type::EnumValue };
598+
599+
result.set<std::string>(std::string { s_namesTaskState[static_cast<size_t>(value)] });
600+
601+
return result;
602+
}
603+
604+
template <>
605+
response::Value ModifiedVariable<CompleteTaskInput>::serialize(CompleteTaskInput&& inputValue)
606+
{
607+
response::Value result { response::Type::Map };
608+
609+
result.emplace_back(R"js(id)js"s, ModifiedVariable<response::IdType>::serialize(std::move(inputValue.id)));
610+
result.emplace_back(R"js(testTaskState)js"s, ModifiedVariable<TaskState>::serialize<TypeModifier::Nullable>(std::move(inputValue.testTaskState)));
611+
result.emplace_back(R"js(isComplete)js"s, ModifiedVariable<bool>::serialize<TypeModifier::Nullable>(std::move(inputValue.isComplete)));
612+
result.emplace_back(R"js(clientMutationId)js"s, ModifiedVariable<std::string>::serialize<TypeModifier::Nullable>(std::move(inputValue.clientMutationId)));
613+
614+
return result;
615+
}
616+
617+
template <>
618+
mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task ModifiedResponse<mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task>::parse(response::Value&& response)
619+
{
620+
mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task result;
621+
622+
if (response.type() == response::Type::Map)
623+
{
624+
auto members = response.release<response::MapType>();
625+
626+
for (auto& member : members)
627+
{
628+
if (member.first == R"js(completedTaskId)js"sv)
629+
{
630+
result.completedTaskId = ModifiedResponse<response::IdType>::parse(std::move(member.second));
631+
continue;
632+
}
633+
if (member.first == R"js(title)js"sv)
634+
{
635+
result.title = ModifiedResponse<std::string>::parse<TypeModifier::Nullable>(std::move(member.second));
636+
continue;
637+
}
638+
if (member.first == R"js(isComplete)js"sv)
639+
{
640+
result.isComplete = ModifiedResponse<bool>::parse(std::move(member.second));
641+
continue;
642+
}
643+
}
644+
}
645+
646+
return result;
647+
}
648+
649+
template <>
650+
mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload ModifiedResponse<mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload>::parse(response::Value&& response)
651+
{
652+
mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload result;
653+
654+
if (response.type() == response::Type::Map)
655+
{
656+
auto members = response.release<response::MapType>();
657+
658+
for (auto& member : members)
659+
{
660+
if (member.first == R"js(completedTask)js"sv)
661+
{
662+
result.completedTask = ModifiedResponse<mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task>::parse<TypeModifier::Nullable>(std::move(member.second));
663+
continue;
664+
}
665+
if (member.first == R"js(clientMutationId)js"sv)
666+
{
667+
result.clientMutationId = ModifiedResponse<std::string>::parse<TypeModifier::Nullable>(std::move(member.second));
668+
continue;
669+
}
670+
}
671+
}
672+
673+
return result;
674+
}
675+
676+
namespace mutation::CompleteTaskMutation {
677+
678+
const std::string& GetOperationName() noexcept
679+
{
680+
static const auto s_name = R"gql(CompleteTaskMutation)gql"s;
681+
682+
return s_name;
683+
}
684+
685+
response::Value serializeVariables(Variables&& variables)
686+
{
687+
response::Value result { response::Type::Map };
688+
689+
result.emplace_back(R"js(input)js"s, ModifiedVariable<CompleteTaskInput>::serialize<TypeModifier::Nullable>(std::move(variables.input)));
690+
result.emplace_back(R"js(skipClientMutationId)js"s, ModifiedVariable<bool>::serialize(std::move(variables.skipClientMutationId)));
691+
692+
return result;
693+
}
694+
695+
Response parseResponse(response::Value&& response)
696+
{
697+
Response result;
698+
699+
if (response.type() == response::Type::Map)
700+
{
701+
auto members = response.release<response::MapType>();
702+
703+
for (auto& member : members)
704+
{
705+
if (member.first == R"js(completedTask)js"sv)
706+
{
707+
result.completedTask = ModifiedResponse<mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload>::parse(std::move(member.second));
708+
continue;
709+
}
710+
}
711+
}
712+
713+
return result;
714+
}
715+
716+
} // namespace mutation::CompleteTaskMutation
576717
} // namespace graphql::client

samples/client/multiple/MultipleQueriesClient.h

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static_assert(graphql::internal::MinorVersion == 2, "regenerate with clientgen:
2525
namespace graphql::client {
2626

2727
/// <summary>
28-
/// Operations: query Appointments, query Tasks, query UnreadCounts, query Miscellaneous
28+
/// Operations: query Appointments, query Tasks, query UnreadCounts, query Miscellaneous, mutation CompleteTaskMutation
2929
/// </summary>
3030
/// <code class="language-graphql">
3131
/// # Copyright (c) Microsoft Corporation. All rights reserved.
@@ -97,6 +97,17 @@ namespace graphql::client {
9797
/// # Try a field with a C++ keyword
9898
/// default
9999
/// }
100+
///
101+
/// mutation CompleteTaskMutation($input: CompleteTaskInput = {id: "ZmFrZVRhc2tJZA==", isComplete: true, clientMutationId: "Hi There!"}, $skipClientMutationId: Boolean!) {
102+
/// completedTask: completeTask(input: $input) {
103+
/// completedTask: task {
104+
/// completedTaskId: id
105+
/// title
106+
/// isComplete
107+
/// }
108+
/// clientMutationId @skip(if: $skipClientMutationId)
109+
/// }
110+
/// }
100111
/// </code>
101112
namespace multiple {
102113

@@ -114,6 +125,14 @@ enum class [[nodiscard]] TaskState
114125
Unassigned,
115126
};
116127

128+
struct CompleteTaskInput
129+
{
130+
response::IdType id {};
131+
std::optional<TaskState> testTaskState {};
132+
std::optional<bool> isComplete {};
133+
std::optional<std::string> clientMutationId {};
134+
};
135+
117136
} // namespace multiple
118137

119138
namespace query::Appointments {
@@ -253,6 +272,48 @@ struct Response
253272
Response parseResponse(response::Value&& response);
254273

255274
} // namespace query::Miscellaneous
275+
276+
namespace mutation::CompleteTaskMutation {
277+
278+
using multiple::GetRequestText;
279+
using multiple::GetRequestObject;
280+
281+
// Return the name of this operation in the shared request document.
282+
const std::string& GetOperationName() noexcept;
283+
284+
using multiple::TaskState;
285+
286+
using multiple::CompleteTaskInput;
287+
288+
struct Variables
289+
{
290+
std::unique_ptr<CompleteTaskInput> input {};
291+
bool skipClientMutationId {};
292+
};
293+
294+
response::Value serializeVariables(Variables&& variables);
295+
296+
struct Response
297+
{
298+
struct completedTask_CompleteTaskPayload
299+
{
300+
struct completedTask_Task
301+
{
302+
response::IdType completedTaskId {};
303+
std::optional<std::string> title {};
304+
bool isComplete {};
305+
};
306+
307+
std::optional<completedTask_Task> completedTask {};
308+
std::optional<std::string> clientMutationId {};
309+
};
310+
311+
completedTask_CompleteTaskPayload completedTask {};
312+
};
313+
314+
Response parseResponse(response::Value&& response);
315+
316+
} // namespace mutation::CompleteTaskMutation
256317
} // namespace graphql::client
257318

258319
#endif // MULTIPLEQUERIESCLIENT_H

samples/client/multiple/multiple.today.graphql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,14 @@ query Miscellaneous {
6767
# Try a field with a C++ keyword
6868
default
6969
}
70+
71+
mutation CompleteTaskMutation($input: CompleteTaskInput = {id: "ZmFrZVRhc2tJZA==", isComplete: true, clientMutationId: "Hi There!"}, $skipClientMutationId: Boolean!) {
72+
completedTask: completeTask(input: $input) {
73+
completedTask: task {
74+
completedTaskId: id
75+
title
76+
isComplete
77+
}
78+
clientMutationId @skip(if: $skipClientMutationId)
79+
}
80+
}

src/ClientGenerator.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,6 @@ using namespace std::literals;
567567

568568
const auto& operations = _requestLoader.getOperations();
569569
std::unordered_set<std::string_view> outputEnumNames;
570-
std::unordered_set<std::string_view> outputIsInputType;
571570

572571
for (const auto& operation : operations)
573572
{
@@ -612,6 +611,11 @@ using namespace )cpp"
612611

613612
pendingSeparator.add();
614613

614+
std::unordered_set<std::string_view> outputIsInputType;
615+
std::unordered_set<std::string_view> outputModifiedVariableEnum;
616+
std::unordered_set<std::string_view> outputModifiedVariableInput;
617+
std::unordered_set<std::string_view> outputModifiedResponseEnum;
618+
615619
for (const auto& operation : operations)
616620
{
617621
for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation))
@@ -642,10 +646,15 @@ constexpr bool isInputType<)cpp"
642646
{
643647
for (const auto& enumType : _requestLoader.getReferencedEnums(operation))
644648
{
645-
pendingSeparator.reset();
646-
647649
const auto cppType = _schemaLoader.getCppType(enumType->name());
648650

651+
if (!outputModifiedVariableEnum.insert(cppType).second)
652+
{
653+
continue;
654+
}
655+
656+
pendingSeparator.reset();
657+
649658
if (!variables.empty())
650659
{
651660
sourceFile << R"cpp(template <>
@@ -667,10 +676,15 @@ response::Value ModifiedVariable<)cpp"
667676

668677
for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation))
669678
{
670-
pendingSeparator.reset();
671-
672679
const auto cppType = _schemaLoader.getCppType(inputType.type->name());
673680

681+
if (!outputModifiedVariableInput.insert(cppType).second)
682+
{
683+
continue;
684+
}
685+
686+
pendingSeparator.reset();
687+
674688
sourceFile << R"cpp(template <>
675689
response::Value ModifiedVariable<)cpp"
676690
<< cppType << R"cpp(>::serialize()cpp" << cppType
@@ -705,10 +719,15 @@ response::Value ModifiedVariable<)cpp"
705719

706720
for (const auto& enumType : _requestLoader.getReferencedEnums(operation))
707721
{
708-
pendingSeparator.reset();
709-
710722
const auto cppType = _schemaLoader.getCppType(enumType->name());
711723

724+
if (!outputModifiedResponseEnum.insert(cppType).second)
725+
{
726+
continue;
727+
}
728+
729+
pendingSeparator.reset();
730+
712731
sourceFile << R"cpp(template <>
713732
)cpp" << cppType << R"cpp( ModifiedResponse<)cpp"
714733
<< cppType << R"cpp(>::parse(response::Value&& value)

0 commit comments

Comments
 (0)