Skip to content

Commit

Permalink
[cpp-restsdk] add support for oneOf via std::variant (#18821)
Browse files Browse the repository at this point in the history
* Revert "Revert "[cpp-restsdk] add support for oneOf via std::variant (#18474)…"

This reverts commit 8d39871.

* update samples

* update pom

* set cxx 17

* Revert "set cxx 17"

This reverts commit 0cec8f7.

* install clang 6.0

* Update CI/circle_parallel.sh

Co-authored-by: Amin Yahyaabadi <[email protected]>

* fix include

---------

Co-authored-by: Amin Yahyaabadi <[email protected]>
  • Loading branch information
wing328 and aminya authored Jun 7, 2024
1 parent 3aba427 commit 4be5971
Show file tree
Hide file tree
Showing 27 changed files with 646 additions and 59 deletions.
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()

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 @@ -8,6 +8,11 @@
#ifndef {{modelHeaderGuardPrefix}}_{{classname}}_H_
#define {{modelHeaderGuardPrefix}}_{{classname}}_H_

{{#oneOf}}
{{#-first}}
#include <variant>
{{/-first}}
{{/oneOf}}
{{^parent}}
{{{defaultInclude}}}
#include "{{packageName}}/ModelBase.h"
Expand All @@ -24,6 +29,60 @@ namespace {{this}} {
{{#vendorExtensions.x-forward-declarations}}{{.}}
{{/vendorExtensions.x-forward-declarations}}
{{/vendorExtensions.x-has-forward-declarations}}
{{#oneOf}}{{#-first}}

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 +179,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

0 comments on commit 4be5971

Please sign in to comment.