Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cpp-restsdk] add support for oneOf via std::variant #18474

Merged
merged 9 commits into from
Jun 1, 2024
2 changes: 1 addition & 1 deletion docs/generators/cpp-restsdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|Union|✗|OAS3
|allOf|✗|OAS2,OAS3
|anyOf|✗|OAS3
|oneOf||OAS3
|oneOf||OAS3
|not|✗|OAS3

### Security Feature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public CppRestSdkClientCodegen() {
GlobalFeature.MultiServer
)
.includeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
SchemaSupportFeature.Polymorphism,
SchemaSupportFeature.oneOf
)
.excludeParameterFeatures(
ParameterFeature.Cookie
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
{{/authMethods}}
return m_ApiClient->callApi(localVarPath, utility::conversions::to_string_t("{{httpMethod}}"), localVarQueryParams, localVarHttpBody, localVarHeaderParams, localVarFormParams, localVarFileParams, localVarRequestHttpContentType)
.then([=](web::http::http_response localVarResponse)
.then([=, this](web::http::http_response localVarResponse)
{
if (m_ApiClient->getResponseHandler())
{
Expand Down Expand Up @@ -299,7 +299,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
{{#vendorExtensions.x-codegen-response-ishttpcontent}}
return localVarResponse.extract_vector();
})
.then([=](std::vector<unsigned char> localVarResponse)
.then([=, this](std::vector<unsigned char> localVarResponse)
{
{{{returnType}}} localVarResult = std::make_shared<HttpContent>();
std::shared_ptr<std::stringstream> stream = std::make_shared<std::stringstream>(std::string(localVarResponse.begin(), localVarResponse.end()));
Expand All @@ -309,7 +309,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
{{^vendorExtensions.x-codegen-response-ishttpcontent}}
return localVarResponse.extract_string();
})
.then([=](utility::string_t localVarResponse)
.then([=, this](utility::string_t localVarResponse)
{
{{^returnType}}
return void();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,27 @@
#
# NOTE: Auto generated by OpenAPI Generator (https://openapi-generator.tech).

cmake_minimum_required (VERSION 3.1)
cmake_minimum_required (VERSION 3.5)

project({{{packageName}}})
project({{{packageName}}} CXX)

# Force -fPIC even if the project is configured for building a static library.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CXX_STANDARD_REQUIRED ON)

set(CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
if(DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX20_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 20)
elseif(DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX17_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 17)
elseif(DEFINED CMAKE_CXX14_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX14_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 14)
else()
set(CMAKE_CXX_STANDARD 11)
endif()
endif()

if(NOT CMAKE_BUILD_TYPE)
Expand All @@ -38,12 +49,12 @@ add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
target_compile_options(${PROJECT_NAME}
PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wno-unused-variable>
-Wall -Wno-unused-variable -Wno-unused-lambda-capture>
)

target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

Expand Down Expand Up @@ -90,4 +101,4 @@ install(
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,61 @@ namespace {{this}} {
{{#vendorExtensions.x-forward-declarations}}{{.}}
{{/vendorExtensions.x-forward-declarations}}
{{/vendorExtensions.x-has-forward-declarations}}
{{#oneOf}}{{#-first}}
#include <variant>

class {{declspec}} {{classname}}
{
public:
{{classname}}() = default;
~{{classname}}() = default;

/////////////////////////////////////////////

void validate();

web::json::value toJson() const;

template<typename Target>
bool fromJson(const web::json::value& json) {
// convert json to Target type
Target target;
if (!target.fromJson(json)) {
return false;
}

m_variantValue = target;
return true;
}

void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const;

template<typename Target>
bool fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) {
// convert multipart to Target type
Target target;
if (!target.fromMultiPart(multipart, namePrefix)) {
return false;
}

m_variantValue = target;
return true;
}

/////////////////////////////////////////////
/// {{classname}} members

using VariantType = std::variant<{{#oneOf}}{{^-first}}, {{/-first}}{{{.}}}{{/oneOf}}>;

const VariantType& getVariant() const;
void setVariant(VariantType value);

protected:
VariantType m_variantValue;
};

{{/-first}}{{/oneOf}}
{{^oneOf}}
{{#isEnum}}
class {{declspec}} {{classname}}
: public {{{parent}}}{{^parent}}ModelBase{{/parent}}
Expand Down Expand Up @@ -120,6 +175,7 @@ protected:
};

{{/isEnum}}
{{/oneOf}}

{{#modelNamespaceDeclarations}}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,56 @@
{{#modelNamespaceDeclarations}}
namespace {{this}} {
{{/modelNamespaceDeclarations}}
{{#oneOf}}{{#-first}}

void {{classname}}::validate()
{
// TODO: implement validation
}

const {{classname}}::VariantType& {{classname}}::getVariant() const
{
return m_variantValue;
}

void {{classname}}::setVariant({{classname}}::VariantType value)
{
m_variantValue = value;
}

web::json::value {{classname}}::toJson() const
{
web::json::value val = web::json::value::object();
std::visit([&](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::monostate>) {
val = web::json::value::null();
} else {
val = arg.toJson();
}
}, m_variantValue);

return val;
}

void {{classname}}::toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix) const
{
std::visit([&](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (!std::is_same_v<T, std::monostate>) {
arg.toMultipart(multipart, prefix);
}
}, m_variantValue);
}

{{#oneOf}}
template bool {{classname}}::fromJson<{{.}}>(const web::json::value& json);
template bool {{classname}}::fromMultiPart<{{.}}>(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix);
{{/oneOf}}

{{/-first}}{{/oneOf}}
{{^oneOf}}
{{#isEnum}}

namespace
Expand Down Expand Up @@ -269,6 +318,7 @@ void {{classname}}::unset{{name}}()
{{/isInherited}}
{{/vars}}
{{/isEnum}}
{{/oneOf}}
{{#modelNamespaceDeclarations}}
}
{{/modelNamespaceDeclarations}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,27 @@ paths:
description: User not found
security:
- api_key: []
/user_or_pet:
post:
tags:
- user_or_pet
summary: Create user or pet
description: This can only be done by the logged in user or pet.
operationId: createUserOrPet
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/User'
- $ref: '#/components/schemas/Pet'
description: Created user or pet object
required: true
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ include/CppRestPetstoreClient/Object.h
include/CppRestPetstoreClient/api/PetApi.h
include/CppRestPetstoreClient/api/StoreApi.h
include/CppRestPetstoreClient/api/UserApi.h
include/CppRestPetstoreClient/api/UserOrPetApi.h
include/CppRestPetstoreClient/model/ApiResponse.h
include/CppRestPetstoreClient/model/Category.h
include/CppRestPetstoreClient/model/CreateUserOrPet_request.h
include/CppRestPetstoreClient/model/Order.h
include/CppRestPetstoreClient/model/Pet.h
include/CppRestPetstoreClient/model/SchemaWithSet.h
Expand All @@ -37,8 +39,10 @@ src/Object.cpp
src/api/PetApi.cpp
src/api/StoreApi.cpp
src/api/UserApi.cpp
src/api/UserOrPetApi.cpp
src/model/ApiResponse.cpp
src/model/Category.cpp
src/model/CreateUserOrPet_request.cpp
src/model/Order.cpp
src/model/Pet.cpp
src/model/SchemaWithSet.cpp
Expand Down
25 changes: 18 additions & 7 deletions samples/client/petstore/cpp-restsdk/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,27 @@
#
# NOTE: Auto generated by OpenAPI Generator (https://openapi-generator.tech).

cmake_minimum_required (VERSION 3.1)
cmake_minimum_required (VERSION 3.5)

project(CppRestPetstoreClient)
project(CppRestPetstoreClient CXX)

# Force -fPIC even if the project is configured for building a static library.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CXX_STANDARD_REQUIRED ON)

set(CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
if(DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX20_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 20)
elseif(DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX17_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 17)
elseif(DEFINED CMAKE_CXX14_STANDARD_COMPILE_OPTION OR
DEFINED CMAKE_CXX14_EXTENSION_COMPILE_OPTION)
set(CMAKE_CXX_STANDARD 14)
else()
set(CMAKE_CXX_STANDARD 11)
endif()
endif()

if(NOT CMAKE_BUILD_TYPE)
Expand All @@ -38,12 +49,12 @@ add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
target_compile_options(${PROJECT_NAME}
PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wno-unused-variable>
-Wall -Wno-unused-variable -Wno-unused-lambda-capture>
)

target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

Expand Down Expand Up @@ -90,4 +101,4 @@ install(
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
)
Loading
Loading