Skip to content

Commit 4be5971

Browse files
wing328aminya
andauthored
[cpp-restsdk] add support for oneOf via std::variant (OpenAPITools#18821)
* Revert "Revert "[cpp-restsdk] add support for oneOf via std::variant (OpenAPITools#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]>
1 parent 3aba427 commit 4be5971

File tree

27 files changed

+646
-59
lines changed

27 files changed

+646
-59
lines changed

CI/circle_parallel.sh

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ elif [ "$NODE_INDEX" = "2" ]; then
4141

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

4549
# run go integration tests
4650
(cd samples/client/petstore/go && mvn integration-test)

docs/generators/cpp-restsdk.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
249249
|Union|✗|OAS3
250250
|allOf|✗|OAS2,OAS3
251251
|anyOf|✗|OAS3
252-
|oneOf||OAS3
252+
|oneOf||OAS3
253253
|not|✗|OAS3
254254

255255
### Security Feature

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppRestSdkClientCodegen.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ public CppRestSdkClientCodegen() {
105105
GlobalFeature.MultiServer
106106
)
107107
.includeSchemaSupportFeatures(
108-
SchemaSupportFeature.Polymorphism
108+
SchemaSupportFeature.Polymorphism,
109+
SchemaSupportFeature.oneOf
109110
)
110111
.excludeParameterFeatures(
111112
ParameterFeature.Cookie

modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/api-source.mustache

+3-3
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
265265
{{/authMethods}}
266266
267267
return m_ApiClient->callApi(localVarPath, utility::conversions::to_string_t("{{httpMethod}}"), localVarQueryParams, localVarHttpBody, localVarHeaderParams, localVarFormParams, localVarFileParams, localVarRequestHttpContentType)
268-
.then([=](web::http::http_response localVarResponse)
268+
.then([=, this](web::http::http_response localVarResponse)
269269
{
270270
if (m_ApiClient->getResponseHandler())
271271
{
@@ -299,7 +299,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
299299
{{#vendorExtensions.x-codegen-response-ishttpcontent}}
300300
return localVarResponse.extract_vector();
301301
})
302-
.then([=](std::vector<unsigned char> localVarResponse)
302+
.then([=, this](std::vector<unsigned char> localVarResponse)
303303
{
304304
{{{returnType}}} localVarResult = std::make_shared<HttpContent>();
305305
std::shared_ptr<std::stringstream> stream = std::make_shared<std::stringstream>(std::string(localVarResponse.begin(), localVarResponse.end()));
@@ -309,7 +309,7 @@ pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{
309309
{{^vendorExtensions.x-codegen-response-ishttpcontent}}
310310
return localVarResponse.extract_string();
311311
})
312-
.then([=](utility::string_t localVarResponse)
312+
.then([=, this](utility::string_t localVarResponse)
313313
{
314314
{{^returnType}}
315315
return void();

modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/cmake-lists.mustache

+18-7
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,27 @@
88
#
99
# NOTE: Auto generated by OpenAPI Generator (https://openapi-generator.tech).
1010

11-
cmake_minimum_required (VERSION 3.1)
11+
cmake_minimum_required (VERSION 3.5)
1212

13-
project({{{packageName}}})
13+
project({{{packageName}}} CXX)
1414

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

18+
set(CXX_STANDARD_REQUIRED ON)
1919
if(NOT CMAKE_CXX_STANDARD)
20-
set(CMAKE_CXX_STANDARD 14)
20+
if(DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION OR
21+
DEFINED CMAKE_CXX20_EXTENSION_COMPILE_OPTION)
22+
set(CMAKE_CXX_STANDARD 20)
23+
elseif(DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION OR
24+
DEFINED CMAKE_CXX17_EXTENSION_COMPILE_OPTION)
25+
set(CMAKE_CXX_STANDARD 17)
26+
elseif(DEFINED CMAKE_CXX14_STANDARD_COMPILE_OPTION OR
27+
DEFINED CMAKE_CXX14_EXTENSION_COMPILE_OPTION)
28+
set(CMAKE_CXX_STANDARD 14)
29+
else()
30+
set(CMAKE_CXX_STANDARD 11)
31+
endif()
2132
endif()
2233

2334
if(NOT CMAKE_BUILD_TYPE)
@@ -38,12 +49,12 @@ add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
3849
target_compile_options(${PROJECT_NAME}
3950
PRIVATE
4051
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
41-
-Wall -Wno-unused-variable>
52+
-Wall -Wno-unused-variable -Wno-unused-lambda-capture>
4253
)
4354

4455
target_include_directories(${PROJECT_NAME}
4556
PUBLIC
46-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
57+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
4758
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
4859
)
4960

@@ -90,4 +101,4 @@ install(
90101
install(
91102
EXPORT ${PROJECT_NAME}Targets
92103
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
93-
)
104+
)

modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/model-header.mustache

+60
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
#ifndef {{modelHeaderGuardPrefix}}_{{classname}}_H_
99
#define {{modelHeaderGuardPrefix}}_{{classname}}_H_
1010

11+
{{#oneOf}}
12+
{{#-first}}
13+
#include <variant>
14+
{{/-first}}
15+
{{/oneOf}}
1116
{{^parent}}
1217
{{{defaultInclude}}}
1318
#include "{{packageName}}/ModelBase.h"
@@ -24,6 +29,60 @@ namespace {{this}} {
2429
{{#vendorExtensions.x-forward-declarations}}{{.}}
2530
{{/vendorExtensions.x-forward-declarations}}
2631
{{/vendorExtensions.x-has-forward-declarations}}
32+
{{#oneOf}}{{#-first}}
33+
34+
class {{declspec}} {{classname}}
35+
{
36+
public:
37+
{{classname}}() = default;
38+
~{{classname}}() = default;
39+
40+
/////////////////////////////////////////////
41+
42+
void validate();
43+
44+
web::json::value toJson() const;
45+
46+
template<typename Target>
47+
bool fromJson(const web::json::value& json) {
48+
// convert json to Target type
49+
Target target;
50+
if (!target.fromJson(json)) {
51+
return false;
52+
}
53+
54+
m_variantValue = target;
55+
return true;
56+
}
57+
58+
void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const;
59+
60+
template<typename Target>
61+
bool fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) {
62+
// convert multipart to Target type
63+
Target target;
64+
if (!target.fromMultiPart(multipart, namePrefix)) {
65+
return false;
66+
}
67+
68+
m_variantValue = target;
69+
return true;
70+
}
71+
72+
/////////////////////////////////////////////
73+
/// {{classname}} members
74+
75+
using VariantType = std::variant<{{#oneOf}}{{^-first}}, {{/-first}}{{{.}}}{{/oneOf}}>;
76+
77+
const VariantType& getVariant() const;
78+
void setVariant(VariantType value);
79+
80+
protected:
81+
VariantType m_variantValue;
82+
};
83+
84+
{{/-first}}{{/oneOf}}
85+
{{^oneOf}}
2786
{{#isEnum}}
2887
class {{declspec}} {{classname}}
2988
: public {{{parent}}}{{^parent}}ModelBase{{/parent}}
@@ -120,6 +179,7 @@ protected:
120179
};
121180

122181
{{/isEnum}}
182+
{{/oneOf}}
123183

124184
{{#modelNamespaceDeclarations}}
125185
}

modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/model-source.mustache

+50
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,56 @@
66
{{#modelNamespaceDeclarations}}
77
namespace {{this}} {
88
{{/modelNamespaceDeclarations}}
9+
{{#oneOf}}{{#-first}}
910

11+
void {{classname}}::validate()
12+
{
13+
// TODO: implement validation
14+
}
15+
16+
const {{classname}}::VariantType& {{classname}}::getVariant() const
17+
{
18+
return m_variantValue;
19+
}
20+
21+
void {{classname}}::setVariant({{classname}}::VariantType value)
22+
{
23+
m_variantValue = value;
24+
}
25+
26+
web::json::value {{classname}}::toJson() const
27+
{
28+
web::json::value val = web::json::value::object();
29+
30+
std::visit([&](auto&& arg) {
31+
using T = std::decay_t<decltype(arg)>;
32+
if constexpr (std::is_same_v<T, std::monostate>) {
33+
val = web::json::value::null();
34+
} else {
35+
val = arg.toJson();
36+
}
37+
}, m_variantValue);
38+
39+
return val;
40+
}
41+
42+
void {{classname}}::toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix) const
43+
{
44+
std::visit([&](auto&& arg) {
45+
using T = std::decay_t<decltype(arg)>;
46+
if constexpr (!std::is_same_v<T, std::monostate>) {
47+
arg.toMultipart(multipart, prefix);
48+
}
49+
}, m_variantValue);
50+
}
51+
52+
{{#oneOf}}
53+
template bool {{classname}}::fromJson<{{.}}>(const web::json::value& json);
54+
template bool {{classname}}::fromMultiPart<{{.}}>(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix);
55+
{{/oneOf}}
56+
57+
{{/-first}}{{/oneOf}}
58+
{{^oneOf}}
1059
{{#isEnum}}
1160

1261
namespace
@@ -269,6 +318,7 @@ void {{classname}}::unset{{name}}()
269318
{{/isInherited}}
270319
{{/vars}}
271320
{{/isEnum}}
321+
{{/oneOf}}
272322
{{#modelNamespaceDeclarations}}
273323
}
274324
{{/modelNamespaceDeclarations}}

modules/openapi-generator/src/test/resources/3_0/cpp-restsdk/petstore.yaml

+21
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,27 @@ paths:
569569
description: User not found
570570
security:
571571
- api_key: []
572+
/user_or_pet:
573+
post:
574+
tags:
575+
- user_or_pet
576+
summary: Create user or pet
577+
description: This can only be done by the logged in user or pet.
578+
operationId: createUserOrPet
579+
responses:
580+
default:
581+
description: successful operation
582+
security:
583+
- api_key: []
584+
requestBody:
585+
content:
586+
application/json:
587+
schema:
588+
oneOf:
589+
- $ref: '#/components/schemas/User'
590+
- $ref: '#/components/schemas/Pet'
591+
description: Created user or pet object
592+
required: true
572593
externalDocs:
573594
description: Find out more about Swagger
574595
url: 'http://swagger.io'

samples/client/petstore/cpp-restsdk/client/.openapi-generator/FILES

+4
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ include/CppRestPetstoreClient/Object.h
1616
include/CppRestPetstoreClient/api/PetApi.h
1717
include/CppRestPetstoreClient/api/StoreApi.h
1818
include/CppRestPetstoreClient/api/UserApi.h
19+
include/CppRestPetstoreClient/api/UserOrPetApi.h
1920
include/CppRestPetstoreClient/model/ApiResponse.h
2021
include/CppRestPetstoreClient/model/Category.h
22+
include/CppRestPetstoreClient/model/CreateUserOrPet_request.h
2123
include/CppRestPetstoreClient/model/Order.h
2224
include/CppRestPetstoreClient/model/Pet.h
2325
include/CppRestPetstoreClient/model/SchemaWithSet.h
@@ -37,8 +39,10 @@ src/Object.cpp
3739
src/api/PetApi.cpp
3840
src/api/StoreApi.cpp
3941
src/api/UserApi.cpp
42+
src/api/UserOrPetApi.cpp
4043
src/model/ApiResponse.cpp
4144
src/model/Category.cpp
45+
src/model/CreateUserOrPet_request.cpp
4246
src/model/Order.cpp
4347
src/model/Pet.cpp
4448
src/model/SchemaWithSet.cpp

samples/client/petstore/cpp-restsdk/client/CMakeLists.txt

+18-7
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,27 @@
88
#
99
# NOTE: Auto generated by OpenAPI Generator (https://openapi-generator.tech).
1010

11-
cmake_minimum_required (VERSION 3.1)
11+
cmake_minimum_required (VERSION 3.5)
1212

13-
project(CppRestPetstoreClient)
13+
project(CppRestPetstoreClient CXX)
1414

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

18+
set(CXX_STANDARD_REQUIRED ON)
1919
if(NOT CMAKE_CXX_STANDARD)
20-
set(CMAKE_CXX_STANDARD 14)
20+
if(DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION OR
21+
DEFINED CMAKE_CXX20_EXTENSION_COMPILE_OPTION)
22+
set(CMAKE_CXX_STANDARD 20)
23+
elseif(DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION OR
24+
DEFINED CMAKE_CXX17_EXTENSION_COMPILE_OPTION)
25+
set(CMAKE_CXX_STANDARD 17)
26+
elseif(DEFINED CMAKE_CXX14_STANDARD_COMPILE_OPTION OR
27+
DEFINED CMAKE_CXX14_EXTENSION_COMPILE_OPTION)
28+
set(CMAKE_CXX_STANDARD 14)
29+
else()
30+
set(CMAKE_CXX_STANDARD 11)
31+
endif()
2132
endif()
2233

2334
if(NOT CMAKE_BUILD_TYPE)
@@ -38,12 +49,12 @@ add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
3849
target_compile_options(${PROJECT_NAME}
3950
PRIVATE
4051
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
41-
-Wall -Wno-unused-variable>
52+
-Wall -Wno-unused-variable -Wno-unused-lambda-capture>
4253
)
4354

4455
target_include_directories(${PROJECT_NAME}
4556
PUBLIC
46-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
57+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
4758
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
4859
)
4960

@@ -90,4 +101,4 @@ install(
90101
install(
91102
EXPORT ${PROJECT_NAME}Targets
92103
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
93-
)
104+
)

0 commit comments

Comments
 (0)