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 #18821

Merged
merged 9 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CI/circle_parallel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ elif [ "$NODE_INDEX" = "2" ]; then

# install cpprestsdk
sudo apt-get install libcpprest-dev
wget "https://github.com/aminya/setup-cpp/releases/download/v0.37.0/setup-cpp-x64-linux"
chmod +x ./setup-cpp-x64-linux
sudo ./setup-cpp-x64-linux --compiler llvm --cmake true --ninja true
source ~/.cpprc # activate cpp environment variables

# run go integration tests
(cd samples/client/petstore/go && mvn integration-test)
Expand Down
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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some logging to be able to see what is happening. The test would need re-generation.

Suggested change
endif()
endif()
message(STATUS "Using C++ standard ${CMAKE_CXX_STANDARD}")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it's using C++ 11 according to the error message:

In file included from /home/circleci/OpenAPITools/openapi-generator/samples/client/petstore/cpp-restsdk/client/include/CppRestPetstoreClient/model/CreateUserOrPet_request.h:39:
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:116:20: error: no template named 'add_const_t'; did you mean '::std::add_const_t'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the libstdc++ version. But the compiler standard itself could be different.

Copy link
Contributor

@aminya aminya Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the issue! #18821 (comment)


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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move the include towards the top so that it is before the namespaces. Probably before or after {{#imports}}?


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