diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 4628ffd4..8ce60019 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -77,17 +77,17 @@ template return false; } +// Special-case an innermost nullable INPUT_OBJECT type. +template +[[nodiscard]] constexpr bool onlyNoneModifiers() noexcept +{ + return (... && (Other == TypeModifier::None)); +} + // Serialize variable input values with chained type modifiers which add nullable or list wrappers. template struct ModifiedVariable { - // Special-case an innermost nullable INPUT_OBJECT type. - template - [[nodiscard]] static constexpr bool onlyNoneModifiers() noexcept - { - return (... && (Other == TypeModifier::None)); - } - // Peel off modifiers until we get to the underlying type. template struct VariableTraits @@ -152,6 +152,53 @@ struct ModifiedVariable return result; } + + // Peel off the none modifier. If it's included, it should always be last in the list. + template + [[nodiscard]] static + typename std::enable_if_t + duplicate(const Type& value) + { + // Just copy the value. + return Type { value }; + } + + // Peel off nullable modifiers. + template + [[nodiscard]] static typename std::enable_if_t::type> + duplicate(const typename VariableTraits::type& nullableValue) + { + typename VariableTraits::type result {}; + + if (nullableValue) + { + if constexpr (isInputType() && onlyNoneModifiers()) + { + // Special case duplicating the std::unique_ptr. + result = std::make_unique(Type { *nullableValue }); + } + else + { + result = duplicate(*nullableValue); + } + } + + return result; + } + + // Peel off list modifiers. + template + [[nodiscard]] static typename std::enable_if_t::type> + duplicate(const typename VariableTraits::type& listValue) + { + typename VariableTraits::type result(listValue.size()); + + std::transform(listValue.cbegin(), listValue.cend(), result.begin(), duplicate); + + return result; + } }; // Convenient type aliases for testing, generated code won't actually use these. These are also diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index fc150125..8e3146a3 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -146,6 +146,9 @@ template <> GRAPHQLRESPONSE_EXPORT IdType::IdType( typename ByteData::const_pointer begin, typename ByteData::const_pointer end); template <> +GRAPHQLRESPONSE_EXPORT IdType::IdType( + typename ByteData::pointer begin, typename ByteData::pointer end); +template <> GRAPHQLRESPONSE_EXPORT const IdType::ByteData& IdType::get() const; template <> GRAPHQLRESPONSE_EXPORT const IdType::OpaqueString& IdType::get() const; diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 49877796..f9db1192 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -599,6 +599,13 @@ template return false; } +// Special-case an innermost nullable INPUT_OBJECT type. +template +[[nodiscard]] constexpr bool onlyNoneModifiers() noexcept +{ + return (... && (Other == TypeModifier::None)); +} + // Extract individual arguments with chained type modifiers which add nullable or list wrappers. // If the argument is not optional, use require and let it throw a schema_exception when the // argument is missing or not the correct type. If it's optional, use find and check the second @@ -606,13 +613,6 @@ template template struct ModifiedArgument { - // Special-case an innermost nullable INPUT_OBJECT type. - template - [[nodiscard]] static constexpr bool onlyNoneModifiers() noexcept - { - return (... && (Other == TypeModifier::None)); - } - // Peel off modifiers until we get to the underlying type. template struct ArgumentTraits @@ -747,6 +747,53 @@ struct ModifiedArgument return { typename ArgumentTraits::type {}, false }; } } + + // Peel off the none modifier. If it's included, it should always be last in the list. + template + [[nodiscard]] static + typename std::enable_if_t + duplicate(const Type& value) + { + // Just copy the value. + return Type { value }; + } + + // Peel off nullable modifiers. + template + [[nodiscard]] static typename std::enable_if_t::type> + duplicate(const typename ArgumentTraits::type& nullableValue) + { + typename ArgumentTraits::type result {}; + + if (nullableValue) + { + if constexpr (isInputType() && onlyNoneModifiers()) + { + // Special case duplicating the std::unique_ptr. + result = std::make_unique(Type { *nullableValue }); + } + else + { + result = duplicate(*nullableValue); + } + } + + return result; + } + + // Peel off list modifiers. + template + [[nodiscard]] static typename std::enable_if_t::type> + duplicate(const typename ArgumentTraits::type& listValue) + { + typename ArgumentTraits::type result(listValue.size()); + + std::transform(listValue.cbegin(), listValue.cend(), result.begin(), duplicate); + + return result; + } }; // Convenient type aliases for testing, generated code won't actually use these. These are also diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/BenchmarkClient.cpp index 573b4b6c..e03d57d7 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/BenchmarkClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 4b082ebf..0e65f979 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; @@ -125,6 +126,53 @@ static const std::array s_namesTaskState = { "Unassigned"sv, }; +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} + +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { ModifiedVariable::duplicate(other.id) } + , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } + , isComplete { ModifiedVariable::duplicate(other.isComplete) } + , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } +{ +} + +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) +{ + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; +} + } // namespace multiple using namespace multiple; @@ -585,12 +633,6 @@ Response parseResponse(response::Value&& response) } // namespace query::Miscellaneous -template <> -constexpr bool isInputType() noexcept -{ - return true; -} - template <> response::Value ModifiedVariable::serialize(TaskState&& value) { diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 9e4877ec..0e6f8453 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -127,6 +127,17 @@ enum class [[nodiscard]] TaskState struct [[nodiscard]] CompleteTaskInput { + explicit CompleteTaskInput( + response::IdType idArg = response::IdType {}, + std::optional testTaskStateArg = std::optional {}, + std::optional isCompleteArg = std::optional {}, + std::optional clientMutationIdArg = std::optional {}) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + response::IdType id {}; std::optional testTaskState {}; std::optional isComplete {}; @@ -135,6 +146,12 @@ struct [[nodiscard]] CompleteTaskInput } // namespace multiple +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + namespace query::Appointments { using multiple::GetRequestText; diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index d12c8d4f..9e48d888 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; @@ -58,16 +59,57 @@ static const std::array s_namesTaskState = { "Unassigned"sv, }; -} // namespace mutate +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} -using namespace mutate; +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { ModifiedVariable::duplicate(other.id) } + , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } + , isComplete { ModifiedVariable::duplicate(other.isComplete) } + , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } +{ +} -template <> -constexpr bool isInputType() noexcept +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) { - return true; + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; } +} // namespace mutate + +using namespace mutate; + template <> response::Value ModifiedVariable::serialize(TaskState&& value) { diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 082a734d..84c7b0f8 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -60,6 +60,17 @@ enum class [[nodiscard]] TaskState struct [[nodiscard]] CompleteTaskInput { + explicit CompleteTaskInput( + response::IdType idArg = response::IdType {}, + std::optional testTaskStateArg = std::optional {}, + std::optional isCompleteArg = std::optional {}, + std::optional clientMutationIdArg = std::optional {}) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + response::IdType id {}; std::optional testTaskState {}; std::optional isComplete {}; @@ -68,6 +79,12 @@ struct [[nodiscard]] CompleteTaskInput } // namespace mutate +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + namespace mutation::CompleteTaskMutation { using mutate::GetRequestText; diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index fcec6099..54bebdb3 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; @@ -45,34 +46,158 @@ const peg::ast& GetRequestObject() noexcept return s_request; } -} // namespace nestedinput +InputA::InputA( + bool aArg) noexcept + : a { std::move(aArg) } +{ +} -using namespace nestedinput; +InputA::InputA(const InputA& other) + : a { ModifiedVariable::duplicate(other.a) } +{ +} -template <> -constexpr bool isInputType() noexcept +InputA::InputA(InputA&& other) noexcept + : a { std::move(other.a) } { - return true; } -template <> -constexpr bool isInputType() noexcept +InputA& InputA::operator=(const InputA& other) { - return true; + InputA value { other }; + + std::swap(*this, value); + + return *this; } -template <> -constexpr bool isInputType() noexcept +InputA& InputA::operator=(InputA&& other) noexcept { - return true; + a = std::move(other.a); + + return *this; } -template <> -constexpr bool isInputType() noexcept +InputB::InputB( + double bArg) noexcept + : b { std::move(bArg) } +{ +} + +InputB::InputB(const InputB& other) + : b { ModifiedVariable::duplicate(other.b) } +{ +} + +InputB::InputB(InputB&& other) noexcept + : b { std::move(other.b) } +{ +} + +InputB& InputB::operator=(const InputB& other) +{ + InputB value { other }; + + std::swap(*this, value); + + return *this; +} + +InputB& InputB::operator=(InputB&& other) noexcept +{ + b = std::move(other.b); + + return *this; +} + +InputABCD::InputABCD( + std::string dArg, + InputA aArg, + InputB bArg, + std::vector bcArg) noexcept + : d { std::move(dArg) } + , a { std::move(aArg) } + , b { std::move(bArg) } + , bc { std::move(bcArg) } +{ +} + +InputABCD::InputABCD(const InputABCD& other) + : d { ModifiedVariable::duplicate(other.d) } + , a { ModifiedVariable::duplicate(other.a) } + , b { ModifiedVariable::duplicate(other.b) } + , bc { ModifiedVariable::duplicate(other.bc) } { - return true; } +InputABCD::InputABCD(InputABCD&& other) noexcept + : d { std::move(other.d) } + , a { std::move(other.a) } + , b { std::move(other.b) } + , bc { std::move(other.bc) } +{ +} + +InputABCD& InputABCD::operator=(const InputABCD& other) +{ + InputABCD value { other }; + + std::swap(*this, value); + + return *this; +} + +InputABCD& InputABCD::operator=(InputABCD&& other) noexcept +{ + d = std::move(other.d); + a = std::move(other.a); + b = std::move(other.b); + bc = std::move(other.bc); + + return *this; +} + +InputBC::InputBC( + response::IdType cArg, + InputB bArg) noexcept + : c { std::move(cArg) } + , b { std::move(bArg) } +{ +} + +InputBC::InputBC(const InputBC& other) + : c { ModifiedVariable::duplicate(other.c) } + , b { ModifiedVariable::duplicate(other.b) } +{ +} + +InputBC::InputBC(InputBC&& other) noexcept + : c { std::move(other.c) } + , b { std::move(other.b) } +{ +} + +InputBC& InputBC::operator=(const InputBC& other) +{ + InputBC value { other }; + + std::swap(*this, value); + + return *this; +} + +InputBC& InputBC::operator=(InputBC&& other) noexcept +{ + c = std::move(other.c); + b = std::move(other.b); + + return *this; +} + +} // namespace nestedinput + +using namespace nestedinput; + template <> response::Value ModifiedVariable::serialize(InputA&& inputValue) { diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 8db7f872..45d6fdcc 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -46,11 +46,27 @@ namespace nestedinput { struct [[nodiscard]] InputA { + explicit InputA( + bool aArg = bool {}) noexcept; + InputA(const InputA& other); + InputA(InputA&& other) noexcept; + + InputA& operator=(const InputA& other); + InputA& operator=(InputA&& other) noexcept; + bool a {}; }; struct [[nodiscard]] InputB { + explicit InputB( + double bArg = double {}) noexcept; + InputB(const InputB& other); + InputB(InputB&& other) noexcept; + + InputB& operator=(const InputB& other); + InputB& operator=(InputB&& other) noexcept; + double b {}; }; @@ -58,6 +74,17 @@ struct InputBC; struct [[nodiscard]] InputABCD { + explicit InputABCD( + std::string dArg = std::string {}, + InputA aArg = InputA {}, + InputB bArg = InputB {}, + std::vector bcArg = std::vector {}) noexcept; + InputABCD(const InputABCD& other); + InputABCD(InputABCD&& other) noexcept; + + InputABCD& operator=(const InputABCD& other); + InputABCD& operator=(InputABCD&& other) noexcept; + std::string d {}; InputA a {}; InputB b {}; @@ -66,12 +93,45 @@ struct [[nodiscard]] InputABCD struct [[nodiscard]] InputBC { + explicit InputBC( + response::IdType cArg = response::IdType {}, + InputB bArg = InputB {}) noexcept; + InputBC(const InputBC& other); + InputBC(InputBC&& other) noexcept; + + InputBC& operator=(const InputBC& other); + InputBC& operator=(InputBC&& other) noexcept; + response::IdType c {}; InputB b {}; }; } // namespace nestedinput +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + +template <> +constexpr bool isInputType() noexcept +{ + return true; +} + namespace query::testQuery { using nestedinput::GetRequestText; diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 24413539..6fc3ac91 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index 91d574f3..cf2b6f4f 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std::literals; diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index c374b31a..e7fedee5 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -86,7 +86,7 @@ learn::ReviewInput ModifiedArgument::convert(const response: auto valueStars = service::ModifiedArgument::require("stars", value); auto valueCommentary = service::ModifiedArgument::require("commentary", value); - return { + return learn::ReviewInput { std::move(valueStars), std::move(valueCommentary) }; @@ -96,6 +96,43 @@ learn::ReviewInput ModifiedArgument::convert(const response: namespace learn { +ReviewInput::ReviewInput( + int starsArg, + std::optional commentaryArg) noexcept + : stars { std::move(starsArg) } + , commentary { std::move(commentaryArg) } +{ +} + +ReviewInput::ReviewInput(const ReviewInput& other) + : stars { service::ModifiedArgument::duplicate(other.stars) } + , commentary { service::ModifiedArgument::duplicate(other.commentary) } +{ +} + +ReviewInput::ReviewInput(ReviewInput&& other) noexcept + : stars { std::move(other.stars) } + , commentary { std::move(other.commentary) } +{ +} + +ReviewInput& ReviewInput::operator=(const ReviewInput& other) +{ + ReviewInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept +{ + stars = std::move(other.stars); + commentary = std::move(other.commentary); + + return *this; +} + Operations::Operations(std::shared_ptr query, std::shared_ptr mutation) : service::Request({ { service::strQuery, query }, diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index dbf48dcc..39050b66 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -53,6 +53,15 @@ enum class [[nodiscard]] Episode struct [[nodiscard]] ReviewInput { + explicit ReviewInput( + int starsArg = int {}, + std::optional commentaryArg = std::optional {}) noexcept; + ReviewInput(const ReviewInput& other); + ReviewInput(ReviewInput&& other) noexcept; + + ReviewInput& operator=(const ReviewInput& other); + ReviewInput& operator=(ReviewInput&& other) noexcept; + int stars {}; std::optional commentary {}; }; diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index c2ebcd71..773b7b28 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -103,7 +103,7 @@ today::CompleteTaskInput ModifiedArgument::convert(con : service::ModifiedArgument::require("isComplete", defaultValue)); auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); - return { + return today::CompleteTaskInput { std::move(valueId), std::move(valueTestTaskState), std::move(valueIsComplete), @@ -117,7 +117,7 @@ today::ThirdNestedInput ModifiedArgument::convert(const auto valueId = service::ModifiedArgument::require("id", value); auto valueSecond = service::ModifiedArgument::require("second", value); - return { + return today::ThirdNestedInput { std::move(valueId), std::move(valueSecond) }; @@ -128,7 +128,7 @@ today::FourthNestedInput ModifiedArgument::convert(con { auto valueId = service::ModifiedArgument::require("id", value); - return { + return today::FourthNestedInput { std::move(valueId) }; } @@ -138,7 +138,7 @@ today::IncludeNullableSelfInput ModifiedArgument::require("self", value); - return { + return today::IncludeNullableSelfInput { std::move(valueSelf) }; } @@ -148,7 +148,7 @@ today::IncludeNonNullableListSelfInput ModifiedArgument::require("selves", value); - return { + return today::IncludeNonNullableListSelfInput { std::move(valueSelves) }; } @@ -169,7 +169,7 @@ today::StringOperationFilterInput ModifiedArgument::require("endsWith", value); auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); - return { + return today::StringOperationFilterInput { std::move(valueAnd_), std::move(valueOr_), std::move(valueEqual), @@ -191,7 +191,7 @@ today::SecondNestedInput ModifiedArgument::convert(con auto valueId = service::ModifiedArgument::require("id", value); auto valueThird = service::ModifiedArgument::require("third", value); - return { + return today::SecondNestedInput { std::move(valueId), std::move(valueThird) }; @@ -203,7 +203,7 @@ today::ForwardDeclaredInput ModifiedArgument::conve auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); auto valueListSelves = service::ModifiedArgument::require("listSelves", value); - return { + return today::ForwardDeclaredInput { std::move(valueNullableSelf), std::move(valueListSelves) }; @@ -216,7 +216,7 @@ today::FirstNestedInput ModifiedArgument::convert(const auto valueSecond = service::ModifiedArgument::require("second", value); auto valueThird = service::ModifiedArgument::require("third", value); - return { + return today::FirstNestedInput { std::move(valueId), std::move(valueSecond), std::move(valueThird) @@ -227,6 +227,389 @@ today::FirstNestedInput ModifiedArgument::convert(const namespace today { +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} + +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } + , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } + , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } +{ +} + +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) +{ + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; +} + +ThirdNestedInput::ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } +{ +} + +ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } +{ +} + +ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } +{ +} + +ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) +{ + ThirdNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + + return *this; +} + +FourthNestedInput::FourthNestedInput( + response::IdType idArg) noexcept + : id { std::move(idArg) } +{ +} + +FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } +{ +} + +FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept + : id { std::move(other.id) } +{ +} + +FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) +{ + FourthNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept +{ + id = std::move(other.id); + + return *this; +} + +IncludeNullableSelfInput::IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept + : self { std::move(selfArg) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) + : self { service::ModifiedArgument::duplicate(other.self) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept + : self { std::move(other.self) } +{ +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) +{ + IncludeNullableSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept +{ + self = std::move(other.self); + + return *this; +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept + : selves { std::move(selvesArg) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) + : selves { service::ModifiedArgument::duplicate(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept + : selves { std::move(other.selves) } +{ +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) +{ + IncludeNonNullableListSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept +{ + selves = std::move(other.selves); + + return *this; +} + +StringOperationFilterInput::StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept + : and_ { std::move(and_Arg) } + , or_ { std::move(or_Arg) } + , equal { std::move(equalArg) } + , notEqual { std::move(notEqualArg) } + , contains { std::move(containsArg) } + , notContains { std::move(notContainsArg) } + , in { std::move(inArg) } + , notIn { std::move(notInArg) } + , startsWith { std::move(startsWithArg) } + , notStartsWith { std::move(notStartsWithArg) } + , endsWith { std::move(endsWithArg) } + , notEndsWith { std::move(notEndsWithArg) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) + : and_ { service::ModifiedArgument::duplicate(other.and_) } + , or_ { service::ModifiedArgument::duplicate(other.or_) } + , equal { service::ModifiedArgument::duplicate(other.equal) } + , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } + , contains { service::ModifiedArgument::duplicate(other.contains) } + , notContains { service::ModifiedArgument::duplicate(other.notContains) } + , in { service::ModifiedArgument::duplicate(other.in) } + , notIn { service::ModifiedArgument::duplicate(other.notIn) } + , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } + , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } + , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } + , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept + : and_ { std::move(other.and_) } + , or_ { std::move(other.or_) } + , equal { std::move(other.equal) } + , notEqual { std::move(other.notEqual) } + , contains { std::move(other.contains) } + , notContains { std::move(other.notContains) } + , in { std::move(other.in) } + , notIn { std::move(other.notIn) } + , startsWith { std::move(other.startsWith) } + , notStartsWith { std::move(other.notStartsWith) } + , endsWith { std::move(other.endsWith) } + , notEndsWith { std::move(other.notEndsWith) } +{ +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) +{ + StringOperationFilterInput value { other }; + + std::swap(*this, value); + + return *this; +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept +{ + and_ = std::move(other.and_); + or_ = std::move(other.or_); + equal = std::move(other.equal); + notEqual = std::move(other.notEqual); + contains = std::move(other.contains); + notContains = std::move(other.notContains); + in = std::move(other.in); + notIn = std::move(other.notIn); + startsWith = std::move(other.startsWith); + notStartsWith = std::move(other.notStartsWith); + endsWith = std::move(other.endsWith); + notEndsWith = std::move(other.notEndsWith); + + return *this; +} + +SecondNestedInput::SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , third { std::move(thirdArg) } +{ +} + +SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept + : id { std::move(other.id) } + , third { std::move(other.third) } +{ +} + +SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) +{ + SecondNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept +{ + id = std::move(other.id); + third = std::move(other.third); + + return *this; +} + +ForwardDeclaredInput::ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept + : nullableSelf { std::move(nullableSelfArg) } + , listSelves { std::move(listSelvesArg) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) + : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } + , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept + : nullableSelf { std::move(other.nullableSelf) } + , listSelves { std::move(other.listSelves) } +{ +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) +{ + ForwardDeclaredInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept +{ + nullableSelf = std::move(other.nullableSelf); + listSelves = std::move(other.listSelves); + + return *this; +} + +FirstNestedInput::FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } + , third { std::move(thirdArg) } +{ +} + +FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } + , third { std::move(other.third) } +{ +} + +FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) +{ + FirstNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + third = std::move(other.third); + + return *this; +} + Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ { service::strQuery, query }, diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 7c882cf4..4e924633 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -56,37 +56,100 @@ enum class [[nodiscard]] TaskState struct [[nodiscard]] CompleteTaskInput { + explicit CompleteTaskInput( + response::IdType idArg = response::IdType {}, + std::optional testTaskStateArg = std::optional {}, + std::optional isCompleteArg = std::optional {}, + std::optional clientMutationIdArg = std::optional {}) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + response::IdType id {}; std::optional testTaskState {}; std::optional isComplete {}; std::optional clientMutationId {}; }; -struct [[nodiscard]] SecondNestedInput; +struct SecondNestedInput; struct [[nodiscard]] ThirdNestedInput { + explicit ThirdNestedInput( + response::IdType idArg = response::IdType {}, + std::unique_ptr secondArg = std::unique_ptr {}) noexcept; + ThirdNestedInput(const ThirdNestedInput& other); + ThirdNestedInput(ThirdNestedInput&& other) noexcept; + + ThirdNestedInput& operator=(const ThirdNestedInput& other); + ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; + response::IdType id {}; std::unique_ptr second {}; }; struct [[nodiscard]] FourthNestedInput { + explicit FourthNestedInput( + response::IdType idArg = response::IdType {}) noexcept; + FourthNestedInput(const FourthNestedInput& other); + FourthNestedInput(FourthNestedInput&& other) noexcept; + + FourthNestedInput& operator=(const FourthNestedInput& other); + FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; + response::IdType id {}; }; struct [[nodiscard]] IncludeNullableSelfInput { + explicit IncludeNullableSelfInput( + std::unique_ptr selfArg = std::unique_ptr {}) noexcept; + IncludeNullableSelfInput(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; + + IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; + std::unique_ptr self {}; }; struct [[nodiscard]] IncludeNonNullableListSelfInput { + explicit IncludeNonNullableListSelfInput( + std::vector selvesArg = std::vector {}) noexcept; + IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; + + IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; + std::vector selves {}; }; struct [[nodiscard]] StringOperationFilterInput { + explicit StringOperationFilterInput( + std::optional> and_Arg = std::optional> {}, + std::optional> or_Arg = std::optional> {}, + std::optional equalArg = std::optional {}, + std::optional notEqualArg = std::optional {}, + std::optional containsArg = std::optional {}, + std::optional notContainsArg = std::optional {}, + std::optional> inArg = std::optional> {}, + std::optional> notInArg = std::optional> {}, + std::optional startsWithArg = std::optional {}, + std::optional notStartsWithArg = std::optional {}, + std::optional endsWithArg = std::optional {}, + std::optional notEndsWithArg = std::optional {}) noexcept; + StringOperationFilterInput(const StringOperationFilterInput& other); + StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; + + StringOperationFilterInput& operator=(const StringOperationFilterInput& other); + StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; + std::optional> and_ {}; std::optional> or_ {}; std::optional equal {}; @@ -101,20 +164,48 @@ struct [[nodiscard]] StringOperationFilterInput std::optional notEndsWith {}; }; -struct SecondNestedInput +struct [[nodiscard]] SecondNestedInput { + explicit SecondNestedInput( + response::IdType idArg = response::IdType {}, + ThirdNestedInput thirdArg = ThirdNestedInput {}) noexcept; + SecondNestedInput(const SecondNestedInput& other); + SecondNestedInput(SecondNestedInput&& other) noexcept; + + SecondNestedInput& operator=(const SecondNestedInput& other); + SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; + response::IdType id {}; ThirdNestedInput third {}; }; struct [[nodiscard]] ForwardDeclaredInput { + explicit ForwardDeclaredInput( + std::unique_ptr nullableSelfArg = std::unique_ptr {}, + IncludeNonNullableListSelfInput listSelvesArg = IncludeNonNullableListSelfInput {}) noexcept; + ForwardDeclaredInput(const ForwardDeclaredInput& other); + ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; + + ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); + ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; + std::unique_ptr nullableSelf {}; IncludeNonNullableListSelfInput listSelves {}; }; struct [[nodiscard]] FirstNestedInput { + explicit FirstNestedInput( + response::IdType idArg = response::IdType {}, + SecondNestedInput secondArg = SecondNestedInput {}, + ThirdNestedInput thirdArg = ThirdNestedInput {}) noexcept; + FirstNestedInput(const FirstNestedInput& other); + FirstNestedInput(FirstNestedInput&& other) noexcept; + + FirstNestedInput& operator=(const FirstNestedInput& other); + FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; + response::IdType id {}; SecondNestedInput second {}; ThirdNestedInput third {}; diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index 77d1a61b..620e85c8 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -103,7 +103,7 @@ today::CompleteTaskInput ModifiedArgument::convert(con : service::ModifiedArgument::require("isComplete", defaultValue)); auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); - return { + return today::CompleteTaskInput { std::move(valueId), std::move(valueTestTaskState), std::move(valueIsComplete), @@ -117,7 +117,7 @@ today::ThirdNestedInput ModifiedArgument::convert(const auto valueId = service::ModifiedArgument::require("id", value); auto valueSecond = service::ModifiedArgument::require("second", value); - return { + return today::ThirdNestedInput { std::move(valueId), std::move(valueSecond) }; @@ -128,7 +128,7 @@ today::FourthNestedInput ModifiedArgument::convert(con { auto valueId = service::ModifiedArgument::require("id", value); - return { + return today::FourthNestedInput { std::move(valueId) }; } @@ -138,7 +138,7 @@ today::IncludeNullableSelfInput ModifiedArgument::require("self", value); - return { + return today::IncludeNullableSelfInput { std::move(valueSelf) }; } @@ -148,7 +148,7 @@ today::IncludeNonNullableListSelfInput ModifiedArgument::require("selves", value); - return { + return today::IncludeNonNullableListSelfInput { std::move(valueSelves) }; } @@ -169,7 +169,7 @@ today::StringOperationFilterInput ModifiedArgument::require("endsWith", value); auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); - return { + return today::StringOperationFilterInput { std::move(valueAnd_), std::move(valueOr_), std::move(valueEqual), @@ -191,7 +191,7 @@ today::SecondNestedInput ModifiedArgument::convert(con auto valueId = service::ModifiedArgument::require("id", value); auto valueThird = service::ModifiedArgument::require("third", value); - return { + return today::SecondNestedInput { std::move(valueId), std::move(valueThird) }; @@ -203,7 +203,7 @@ today::ForwardDeclaredInput ModifiedArgument::conve auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); auto valueListSelves = service::ModifiedArgument::require("listSelves", value); - return { + return today::ForwardDeclaredInput { std::move(valueNullableSelf), std::move(valueListSelves) }; @@ -216,7 +216,7 @@ today::FirstNestedInput ModifiedArgument::convert(const auto valueSecond = service::ModifiedArgument::require("second", value); auto valueThird = service::ModifiedArgument::require("third", value); - return { + return today::FirstNestedInput { std::move(valueId), std::move(valueSecond), std::move(valueThird) @@ -227,6 +227,389 @@ today::FirstNestedInput ModifiedArgument::convert(const namespace today { +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} + +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } + , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } + , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } +{ +} + +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) +{ + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; +} + +ThirdNestedInput::ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } +{ +} + +ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } +{ +} + +ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } +{ +} + +ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) +{ + ThirdNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + + return *this; +} + +FourthNestedInput::FourthNestedInput( + response::IdType idArg) noexcept + : id { std::move(idArg) } +{ +} + +FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } +{ +} + +FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept + : id { std::move(other.id) } +{ +} + +FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) +{ + FourthNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept +{ + id = std::move(other.id); + + return *this; +} + +IncludeNullableSelfInput::IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept + : self { std::move(selfArg) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) + : self { service::ModifiedArgument::duplicate(other.self) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept + : self { std::move(other.self) } +{ +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) +{ + IncludeNullableSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept +{ + self = std::move(other.self); + + return *this; +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept + : selves { std::move(selvesArg) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) + : selves { service::ModifiedArgument::duplicate(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept + : selves { std::move(other.selves) } +{ +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) +{ + IncludeNonNullableListSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept +{ + selves = std::move(other.selves); + + return *this; +} + +StringOperationFilterInput::StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept + : and_ { std::move(and_Arg) } + , or_ { std::move(or_Arg) } + , equal { std::move(equalArg) } + , notEqual { std::move(notEqualArg) } + , contains { std::move(containsArg) } + , notContains { std::move(notContainsArg) } + , in { std::move(inArg) } + , notIn { std::move(notInArg) } + , startsWith { std::move(startsWithArg) } + , notStartsWith { std::move(notStartsWithArg) } + , endsWith { std::move(endsWithArg) } + , notEndsWith { std::move(notEndsWithArg) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) + : and_ { service::ModifiedArgument::duplicate(other.and_) } + , or_ { service::ModifiedArgument::duplicate(other.or_) } + , equal { service::ModifiedArgument::duplicate(other.equal) } + , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } + , contains { service::ModifiedArgument::duplicate(other.contains) } + , notContains { service::ModifiedArgument::duplicate(other.notContains) } + , in { service::ModifiedArgument::duplicate(other.in) } + , notIn { service::ModifiedArgument::duplicate(other.notIn) } + , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } + , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } + , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } + , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept + : and_ { std::move(other.and_) } + , or_ { std::move(other.or_) } + , equal { std::move(other.equal) } + , notEqual { std::move(other.notEqual) } + , contains { std::move(other.contains) } + , notContains { std::move(other.notContains) } + , in { std::move(other.in) } + , notIn { std::move(other.notIn) } + , startsWith { std::move(other.startsWith) } + , notStartsWith { std::move(other.notStartsWith) } + , endsWith { std::move(other.endsWith) } + , notEndsWith { std::move(other.notEndsWith) } +{ +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) +{ + StringOperationFilterInput value { other }; + + std::swap(*this, value); + + return *this; +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept +{ + and_ = std::move(other.and_); + or_ = std::move(other.or_); + equal = std::move(other.equal); + notEqual = std::move(other.notEqual); + contains = std::move(other.contains); + notContains = std::move(other.notContains); + in = std::move(other.in); + notIn = std::move(other.notIn); + startsWith = std::move(other.startsWith); + notStartsWith = std::move(other.notStartsWith); + endsWith = std::move(other.endsWith); + notEndsWith = std::move(other.notEndsWith); + + return *this; +} + +SecondNestedInput::SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , third { std::move(thirdArg) } +{ +} + +SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept + : id { std::move(other.id) } + , third { std::move(other.third) } +{ +} + +SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) +{ + SecondNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept +{ + id = std::move(other.id); + third = std::move(other.third); + + return *this; +} + +ForwardDeclaredInput::ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept + : nullableSelf { std::move(nullableSelfArg) } + , listSelves { std::move(listSelvesArg) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) + : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } + , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept + : nullableSelf { std::move(other.nullableSelf) } + , listSelves { std::move(other.listSelves) } +{ +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) +{ + ForwardDeclaredInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept +{ + nullableSelf = std::move(other.nullableSelf); + listSelves = std::move(other.listSelves); + + return *this; +} + +FirstNestedInput::FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } + , third { std::move(thirdArg) } +{ +} + +FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } + , third { std::move(other.third) } +{ +} + +FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) +{ + FirstNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + third = std::move(other.third); + + return *this; +} + Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ { service::strQuery, query }, diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 7c882cf4..4e924633 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -56,37 +56,100 @@ enum class [[nodiscard]] TaskState struct [[nodiscard]] CompleteTaskInput { + explicit CompleteTaskInput( + response::IdType idArg = response::IdType {}, + std::optional testTaskStateArg = std::optional {}, + std::optional isCompleteArg = std::optional {}, + std::optional clientMutationIdArg = std::optional {}) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + response::IdType id {}; std::optional testTaskState {}; std::optional isComplete {}; std::optional clientMutationId {}; }; -struct [[nodiscard]] SecondNestedInput; +struct SecondNestedInput; struct [[nodiscard]] ThirdNestedInput { + explicit ThirdNestedInput( + response::IdType idArg = response::IdType {}, + std::unique_ptr secondArg = std::unique_ptr {}) noexcept; + ThirdNestedInput(const ThirdNestedInput& other); + ThirdNestedInput(ThirdNestedInput&& other) noexcept; + + ThirdNestedInput& operator=(const ThirdNestedInput& other); + ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; + response::IdType id {}; std::unique_ptr second {}; }; struct [[nodiscard]] FourthNestedInput { + explicit FourthNestedInput( + response::IdType idArg = response::IdType {}) noexcept; + FourthNestedInput(const FourthNestedInput& other); + FourthNestedInput(FourthNestedInput&& other) noexcept; + + FourthNestedInput& operator=(const FourthNestedInput& other); + FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; + response::IdType id {}; }; struct [[nodiscard]] IncludeNullableSelfInput { + explicit IncludeNullableSelfInput( + std::unique_ptr selfArg = std::unique_ptr {}) noexcept; + IncludeNullableSelfInput(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; + + IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; + std::unique_ptr self {}; }; struct [[nodiscard]] IncludeNonNullableListSelfInput { + explicit IncludeNonNullableListSelfInput( + std::vector selvesArg = std::vector {}) noexcept; + IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; + + IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; + std::vector selves {}; }; struct [[nodiscard]] StringOperationFilterInput { + explicit StringOperationFilterInput( + std::optional> and_Arg = std::optional> {}, + std::optional> or_Arg = std::optional> {}, + std::optional equalArg = std::optional {}, + std::optional notEqualArg = std::optional {}, + std::optional containsArg = std::optional {}, + std::optional notContainsArg = std::optional {}, + std::optional> inArg = std::optional> {}, + std::optional> notInArg = std::optional> {}, + std::optional startsWithArg = std::optional {}, + std::optional notStartsWithArg = std::optional {}, + std::optional endsWithArg = std::optional {}, + std::optional notEndsWithArg = std::optional {}) noexcept; + StringOperationFilterInput(const StringOperationFilterInput& other); + StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; + + StringOperationFilterInput& operator=(const StringOperationFilterInput& other); + StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; + std::optional> and_ {}; std::optional> or_ {}; std::optional equal {}; @@ -101,20 +164,48 @@ struct [[nodiscard]] StringOperationFilterInput std::optional notEndsWith {}; }; -struct SecondNestedInput +struct [[nodiscard]] SecondNestedInput { + explicit SecondNestedInput( + response::IdType idArg = response::IdType {}, + ThirdNestedInput thirdArg = ThirdNestedInput {}) noexcept; + SecondNestedInput(const SecondNestedInput& other); + SecondNestedInput(SecondNestedInput&& other) noexcept; + + SecondNestedInput& operator=(const SecondNestedInput& other); + SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; + response::IdType id {}; ThirdNestedInput third {}; }; struct [[nodiscard]] ForwardDeclaredInput { + explicit ForwardDeclaredInput( + std::unique_ptr nullableSelfArg = std::unique_ptr {}, + IncludeNonNullableListSelfInput listSelvesArg = IncludeNonNullableListSelfInput {}) noexcept; + ForwardDeclaredInput(const ForwardDeclaredInput& other); + ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; + + ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); + ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; + std::unique_ptr nullableSelf {}; IncludeNonNullableListSelfInput listSelves {}; }; struct [[nodiscard]] FirstNestedInput { + explicit FirstNestedInput( + response::IdType idArg = response::IdType {}, + SecondNestedInput secondArg = SecondNestedInput {}, + ThirdNestedInput thirdArg = ThirdNestedInput {}) noexcept; + FirstNestedInput(const FirstNestedInput& other); + FirstNestedInput(FirstNestedInput&& other) noexcept; + + FirstNestedInput& operator=(const FirstNestedInput& other); + FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; + response::IdType id {}; SecondNestedInput second {}; ThirdNestedInput third {}; diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index 1566a2d8..96b7d89f 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -143,7 +143,7 @@ validation::ComplexInput ModifiedArgument::convert(con auto valueName = service::ModifiedArgument::require("name", value); auto valueOwner = service::ModifiedArgument::require("owner", value); - return { + return validation::ComplexInput { std::move(valueName), std::move(valueOwner) }; @@ -153,6 +153,43 @@ validation::ComplexInput ModifiedArgument::convert(con namespace validation { +ComplexInput::ComplexInput( + std::optional nameArg, + std::optional ownerArg) noexcept + : name { std::move(nameArg) } + , owner { std::move(ownerArg) } +{ +} + +ComplexInput::ComplexInput(const ComplexInput& other) + : name { service::ModifiedArgument::duplicate(other.name) } + , owner { service::ModifiedArgument::duplicate(other.owner) } +{ +} + +ComplexInput::ComplexInput(ComplexInput&& other) noexcept + : name { std::move(other.name) } + , owner { std::move(other.owner) } +{ +} + +ComplexInput& ComplexInput::operator=(const ComplexInput& other) +{ + ComplexInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ComplexInput& ComplexInput::operator=(ComplexInput&& other) noexcept +{ + name = std::move(other.name); + owner = std::move(other.owner); + + return *this; +} + Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ { service::strQuery, query }, diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 4525c12a..2a4be10c 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -76,6 +76,15 @@ enum class [[nodiscard]] CatCommand struct [[nodiscard]] ComplexInput { + explicit ComplexInput( + std::optional nameArg = std::optional {}, + std::optional ownerArg = std::optional {}) noexcept; + ComplexInput(const ComplexInput& other); + ComplexInput(ComplexInput&& other) noexcept; + + ComplexInput& operator=(const ComplexInput& other); + ComplexInput& operator=(ComplexInput&& other) noexcept; + std::optional name {}; std::optional owner {}; }; diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index dd9cb379..dec484e7 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -271,11 +271,43 @@ static_assert(graphql::internal::MinorVersion == )cpp" headerFile << R"cpp(struct [[nodiscard]] )cpp" << cppType << R"cpp( { -)cpp"; + explicit )cpp" << cppType + << R"cpp(()cpp"; + + bool firstField = true; for (const auto& inputField : inputType.type->inputFields()) { + if (!firstField) + { + headerFile << R"cpp(,)cpp"; + } + + firstField = false; + + const auto inputCppType = _requestLoader.getInputCppType(inputField->type().lock()); + + headerFile << R"cpp( + )cpp" << inputCppType + << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp(Arg = )cpp" << inputCppType << R"cpp( {})cpp"; + } + headerFile << R"cpp() noexcept; + )cpp" << cppType << R"cpp((const )cpp" + << cppType << R"cpp(& other); + )cpp" << cppType << R"cpp(()cpp" + << cppType << R"cpp(&& other) noexcept; + + )cpp" << cppType << R"cpp(& operator=(const )cpp" + << cppType << R"cpp(& other); + )cpp" << cppType << R"cpp(& operator=()cpp" + << cppType << R"cpp(&& other) noexcept; + +)cpp"; + + for (const auto& inputField : inputType.type->inputFields()) + { headerFile << R"cpp( )cpp" << _requestLoader.getInputCppType(inputField->type().lock()) << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) @@ -294,6 +326,34 @@ static_assert(graphql::internal::MinorVersion == )cpp" schemaNamespaceScope.exit(); pendingSeparator.add(); + std::unordered_set outputIsInputType; + + for (const auto& operation : operations) + { + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + { + const auto cppType = _schemaLoader.getCppType(inputType.type->name()); + + if (!outputIsInputType.insert(cppType).second) + { + continue; + } + + pendingSeparator.reset(); + + headerFile << R"cpp(template <> +constexpr bool isInputType<)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType + << R"cpp(>() noexcept +{ + return true; +} +)cpp"; + + pendingSeparator.add(); + } + } + for (const auto& operation : operations) { pendingSeparator.reset(); @@ -486,8 +546,8 @@ bool Generator::outputResponseFieldType(std::ostream& headerFile, std::unordered_set fieldNames; PendingBlankLine pendingSeparator { headerFile }; - headerFile << indentTabs << R"cpp(struct [[nodiscard]] )cpp" << getResponseFieldCppType(responseField) - << R"cpp( + headerFile << indentTabs << R"cpp(struct [[nodiscard]] )cpp" + << getResponseFieldCppType(responseField) << R"cpp( )cpp" << indentTabs << R"cpp({)cpp"; @@ -554,6 +614,7 @@ bool Generator::outputSource() const noexcept #include #include #include +#include using namespace std::literals; @@ -567,6 +628,7 @@ using namespace std::literals; const auto& operations = _requestLoader.getOperations(); std::unordered_set outputEnumNames; + std::unordered_set outputInputMethods; for (const auto& operation : operations) { @@ -601,45 +663,150 @@ using namespace std::literals; } } - pendingSeparator.reset(); - schemaNamespaceScope.exit(); - - sourceFile << R"cpp( -using namespace )cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(; -)cpp"; - - pendingSeparator.add(); - - std::unordered_set outputIsInputType; - std::unordered_set outputModifiedVariableEnum; - std::unordered_set outputModifiedVariableInput; - std::unordered_set outputModifiedResponseEnum; - for (const auto& operation : operations) { for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { const auto cppType = _schemaLoader.getCppType(inputType.type->name()); - if (!outputIsInputType.insert(cppType).second) + if (!outputInputMethods.insert(cppType).second) { continue; } pendingSeparator.reset(); - sourceFile << R"cpp(template <> -constexpr bool isInputType<)cpp" - << cppType << R"cpp(>() noexcept + sourceFile << cppType << R"cpp(::)cpp" << cppType << R"cpp(()cpp"; + + bool firstField = true; + + for (const auto& inputField : inputType.type->inputFields()) + { + if (!firstField) + { + sourceFile << R"cpp(,)cpp"; + } + + firstField = false; + sourceFile << R"cpp( + )cpp" << _requestLoader.getInputCppType(inputField->type().lock()) + << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp(Arg)cpp"; + } + + sourceFile << R"cpp() noexcept +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + const auto name = SchemaLoader::getSafeCppName(inputField->name()); + + sourceFile << name << R"cpp( { std::move()cpp" << name << R"cpp(Arg) } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << cppType << R"cpp(::)cpp" + << cppType << R"cpp((const )cpp" << cppType << R"cpp(& other) +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + const auto name = SchemaLoader::getSafeCppName(inputField->name()); + const auto [type, modifiers] = + RequestLoader::unwrapSchemaType(inputField->type().lock()); + + sourceFile << name << R"cpp( { ModifiedVariable<)cpp" + << _schemaLoader.getCppType(type->name()) << R"cpp(>::duplicate)cpp" + << getTypeModifierList(modifiers) << R"cpp((other.)cpp" << name + << R"cpp() } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << cppType << R"cpp(::)cpp" + << cppType << R"cpp(()cpp" << cppType << R"cpp(&& other) noexcept +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + const auto name = SchemaLoader::getSafeCppName(inputField->name()); + + sourceFile << name << R"cpp( { std::move(other.)cpp" << name << R"cpp() } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << cppType << R"cpp(& )cpp" + << cppType << R"cpp(::operator=(const )cpp" << cppType << R"cpp(& other) { - return true; + )cpp" << cppType << R"cpp( value { other }; + + std::swap(*this, value); + + return *this; +} + +)cpp" << cppType << R"cpp(& )cpp" + << cppType << R"cpp(::operator=()cpp" << cppType << R"cpp(&& other) noexcept +{ +)cpp"; + + for (const auto& inputField : inputType.type->inputFields()) + { + const auto name = SchemaLoader::getSafeCppName(inputField->name()); + + sourceFile << R"cpp( )cpp" << name << R"cpp( = std::move(other.)cpp" << name + << R"cpp(); +)cpp"; + } + + sourceFile << R"cpp( + return *this; } )cpp"; pendingSeparator.add(); } + } + + pendingSeparator.reset(); + schemaNamespaceScope.exit(); + + sourceFile << R"cpp( +using namespace )cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(; +)cpp"; + pendingSeparator.add(); + + std::unordered_set outputModifiedVariableEnum; + std::unordered_set outputModifiedVariableInput; + std::unordered_set outputModifiedResponseEnum; + + for (const auto& operation : operations) + { const auto& variables = _requestLoader.getVariables(operation); if (!variables.empty()) diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index d24309a5..40769732 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -53,6 +53,12 @@ IdType::IdType(typename ByteData::const_pointer begin, typename ByteData::const_ { } +template <> +IdType::IdType(typename ByteData::pointer begin, typename ByteData::pointer end) + : _data { ByteData { begin, end } } +{ +} + IdType& IdType::operator=(IdType&& rhs) noexcept { if (&rhs != this) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 5ad48c31..fa456477 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1794,9 +1794,8 @@ response::AwaitableValue Request::resolve(RequestResolveParams params) const std::move(params.variables), std::move(fragments)); - operationVisitor.visit(operationDefinition.first, *operationDefinition.second); - co_await params.launch; + operationVisitor.visit(operationDefinition.first, *operationDefinition.second); auto result = co_await operationVisitor.getValue(); response::Value document { response::Type::Map }; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 0572a3b4..af827bb3 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -262,19 +262,22 @@ static_assert(graphql::internal::MinorVersion == )cpp" pendingSeparator.reset(); std::unordered_set forwardDeclared; + const auto introspectionExport = + (_loader.isIntrospection() ? "GRAPHQLSERVICE_EXPORT "sv : ""sv); // Output the full declarations for (const auto& inputType : _loader.getInputTypes()) { + forwardDeclared.insert(inputType.cppType); + if (!inputType.declarations.empty()) { // Forward declare nullable dependencies for (auto declaration : inputType.declarations) { - if (declaration != inputType.cppType - && forwardDeclared.insert(declaration).second) + if (forwardDeclared.insert(declaration).second) { - headerFile << R"cpp(struct [[nodiscard]] )cpp" << declaration << R"cpp(; + headerFile << R"cpp(struct )cpp" << declaration << R"cpp(; )cpp"; pendingSeparator.add(); } @@ -283,18 +286,46 @@ static_assert(graphql::internal::MinorVersion == )cpp" pendingSeparator.reset(); } - headerFile << R"cpp(struct )cpp"; + headerFile << R"cpp(struct [[nodiscard]] )cpp" << inputType.cppType << R"cpp( +{ + )cpp" << introspectionExport + << R"cpp(explicit )cpp" << inputType.cppType << R"cpp(()cpp"; + + bool firstField = true; - if (forwardDeclared.find(inputType.cppType) == forwardDeclared.end()) + for (const auto& inputField : inputType.fields) { - headerFile << R"cpp([[nodiscard]] )cpp"; + if (!firstField) + { + headerFile << R"cpp(,)cpp"; + } + + firstField = false; + + const auto inputCppType = _loader.getInputCppType(inputField); + + headerFile << R"cpp( + )cpp" << inputCppType + << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg = )cpp" + << inputCppType << R"cpp( {})cpp"; } - headerFile << inputType.cppType << R"cpp( -{ -)cpp"; + headerFile << R"cpp() noexcept; + )cpp" << introspectionExport + << inputType.cppType << R"cpp((const )cpp" << inputType.cppType + << R"cpp(& other); + )cpp" << introspectionExport + << inputType.cppType << R"cpp(()cpp" << inputType.cppType + << R"cpp(&& other) noexcept; - forwardDeclared.insert(inputType.cppType); + )cpp" << introspectionExport + << inputType.cppType << R"cpp(& operator=(const )cpp" << inputType.cppType + << R"cpp(& other); + )cpp" << introspectionExport + << inputType.cppType << R"cpp(& operator=()cpp" << inputType.cppType + << R"cpp(&& other) noexcept; + +)cpp"; for (const auto& inputField : inputType.fields) { @@ -303,8 +334,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" headerFile << R"cpp(}; )cpp"; - - forwardDeclared.insert(inputType.type); } } @@ -1405,7 +1434,8 @@ void ModifiedResult<)cpp" sourceFile << std::endl; } - sourceFile << R"cpp( return { + sourceFile << R"cpp( return )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << inputType.cppType << R"cpp( { )cpp"; firstField = true; @@ -1440,6 +1470,145 @@ void ModifiedResult<)cpp" NamespaceScope schemaNamespace { sourceFile, _loader.getSchemaNamespace() }; std::string_view queryType; + for (const auto& inputType : _loader.getInputTypes()) + { + sourceFile << std::endl + << inputType.cppType << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp"; + + bool firstField = true; + + for (const auto& inputField : inputType.fields) + { + if (!firstField) + { + sourceFile << R"cpp(,)cpp"; + } + + firstField = false; + sourceFile << R"cpp( + )cpp" << _loader.getInputCppType(inputField) + << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg)cpp"; + } + + sourceFile << R"cpp() noexcept +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.fields) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + sourceFile << inputField.cppName << R"cpp( { std::move()cpp" << inputField.cppName + << R"cpp(Arg) } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << inputType.cppType + << R"cpp(::)cpp" << inputType.cppType << R"cpp((const )cpp" << inputType.cppType + << R"cpp(& other) +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.fields) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + sourceFile << inputField.cppName << R"cpp( { service::ModifiedArgument<)cpp" + << _loader.getCppType(inputField.type) << R"cpp(>::duplicate)cpp"; + + if (!inputField.modifiers.empty()) + { + bool firstModifier = true; + + for (const auto modifier : inputField.modifiers) + { + sourceFile << (firstModifier ? R"cpp(<)cpp" : R"cpp(, )cpp"); + firstModifier = false; + + switch (modifier) + { + case service::TypeModifier::None: + sourceFile << R"cpp(service::TypeModifier::None)cpp"; + break; + + case service::TypeModifier::Nullable: + sourceFile << R"cpp(service::TypeModifier::Nullable)cpp"; + break; + + case service::TypeModifier::List: + sourceFile << R"cpp(service::TypeModifier::List)cpp"; + break; + } + } + + sourceFile << R"cpp(>)cpp"; + } + + sourceFile << R"cpp((other.)cpp" << inputField.cppName << R"cpp() } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << inputType.cppType + << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp" << inputType.cppType + << R"cpp(&& other) noexcept +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.fields) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + sourceFile << inputField.cppName << R"cpp( { std::move(other.)cpp" << inputField.cppName + << R"cpp() } +)cpp"; + } + + sourceFile << R"cpp({ +} + +)cpp" << inputType.cppType + << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=(const )cpp" + << inputType.cppType << R"cpp(& other) +{ + )cpp" << inputType.cppType + << R"cpp( value { other }; + + std::swap(*this, value); + + return *this; +} + +)cpp" << inputType.cppType + << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=()cpp" + << inputType.cppType << R"cpp(&& other) noexcept +{ +)cpp"; + + for (const auto& inputField : inputType.fields) + { + sourceFile << R"cpp( )cpp" << inputField.cppName << R"cpp( = std::move(other.)cpp" + << inputField.cppName << R"cpp(); +)cpp"; + } + + sourceFile << R"cpp( + return *this; +} +)cpp"; + } + if (!_loader.isIntrospection()) { for (const auto& operation : _loader.getOperationTypes()) diff --git a/test/ArgumentTests.cpp b/test/ArgumentTests.cpp index 72e811ae..f1f882e1 100644 --- a/test/ArgumentTests.cpp +++ b/test/ArgumentTests.cpp @@ -348,19 +348,16 @@ TEST(ArgumentsCase, FindArgumentEmptyTemplateArgs) TEST(ArgumentsCase, OnlyNoneModifiers) { - constexpr bool emptyModifiers = service::ModifiedArgument::onlyNoneModifiers<>(); - constexpr bool threeNone = - service::ModifiedArgument::onlyNoneModifiers(); - constexpr bool firtNullable = - service::ModifiedArgument::onlyNoneModifiers(); - constexpr bool middleList = - service::ModifiedArgument::onlyNoneModifiers(); + constexpr bool emptyModifiers = service::onlyNoneModifiers<>(); + constexpr bool threeNone = service::onlyNoneModifiers(); + constexpr bool firtNullable = service::onlyNoneModifiers(); + constexpr bool middleList = service::onlyNoneModifiers(); ASSERT_TRUE(emptyModifiers) << "onlyNoneModifiers<> is true"; ASSERT_TRUE(threeNone) << "onlyNoneModifiers is true";