Skip to content

Commit 359de66

Browse files
[cpp-libcurl] Add oneOf support
1 parent b04331c commit 359de66

13 files changed

Lines changed: 147 additions & 8 deletions

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ public CppLibcurlClientCodegen() {
6868
GlobalFeature.MultiServer
6969
)
7070
.includeSchemaSupportFeatures(
71-
SchemaSupportFeature.Polymorphism
71+
SchemaSupportFeature.Polymorphism,
72+
SchemaSupportFeature.oneOf
7273
)
7374
.excludeParameterFeatures(
7475
ParameterFeature.Cookie

modules/openapi-generator/src/main/resources/cpp-libcurl/model-header.mustache

Lines changed: 24 additions & 1 deletion
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
{{#isEnum}}
@@ -31,6 +36,24 @@ namespace {{this}} {
3136
{{#vendorExtensions.x-forward-declarations}}{{.}}
3237
{{/vendorExtensions.x-forward-declarations}}
3338
{{/vendorExtensions.x-has-forward-declarations}}
39+
{{#oneOf}}{{#-first}}
40+
class {{declspec}} {{classname}} {
41+
public:
42+
nlohmann::json toJson() const;
43+
bool fromJson(const nlohmann::json& json);
44+
45+
using VariantType = std::variant<{{#oneOf}}{{^-first}}, {{/-first}}{{{.}}}{{/oneOf}}>;
46+
47+
const VariantType& getVariant() const;
48+
void setVariant(const VariantType& value);
49+
void setVariant(VariantType&& value);
50+
51+
private:
52+
VariantType m_variantValue;
53+
};
54+
55+
{{/-first}}{{/oneOf}}
56+
{{^oneOf}}
3457
{{#isEnum}}
3558
class {{declspec}} {{classname}}
3659
: public {{{parent}}}{{^parent}}ModelBase{{/parent}} {
@@ -62,7 +85,6 @@ private:
6285
};
6386
{{/isEnum}}
6487
{{^isEnum}}
65-
6688
{{#description}}
6789
/// <summary>
6890
/// {{{description}}}
@@ -130,6 +152,7 @@ private:
130152
};
131153

132154
{{/isEnum}}
155+
{{/oneOf}}
133156

134157
{{#modelNamespaceDeclarations}}
135158
}

modules/openapi-generator/src/main/resources/cpp-libcurl/model-source.mustache

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,50 @@
66
#include <string_view>
77
{{/isNumeric}}
88
{{/isEnum}}
9+
{{#oneOf}}
10+
#include <utility>
11+
{{/oneOf}}
912
#include "{{packageName}}/model/{{classFilename}}.h"
1013

1114
{{#modelNamespaceDeclarations}}
1215
namespace {{this}} {
1316
{{/modelNamespaceDeclarations}}
17+
{{#oneOf}}
18+
{{#-first}}
1419

20+
const {{classname}}::VariantType& {{classname}}::getVariant() const {
21+
return m_variantValue;
22+
}
23+
24+
void {{classname}}::setVariant(const {{classname}}::VariantType& value) {
25+
m_variantValue = value;
26+
}
27+
28+
void {{classname}}::setVariant({{classname}}::VariantType&& value) {
29+
m_variantValue = std::move(value);
30+
}
31+
32+
bool {{classname}}::fromJson(const nlohmann::json& json) {
33+
return ModelBase::fromJson(json, m_variantValue);
34+
}
35+
36+
nlohmann::json {{classname}}::toJson() const {
37+
nlohmann::json val = nlohmann::json::object();
38+
39+
std::visit([&val](const auto& arg) {
40+
using T = std::decay_t<decltype(arg)>;
41+
if constexpr (std::is_same_v<T, std::monostate>) {
42+
val = nullptr;
43+
} else {
44+
val = ModelBase::toJson(arg);
45+
}
46+
}, m_variantValue);
47+
48+
return val;
49+
}
50+
{{/-first}}
51+
{{/oneOf}}
52+
{{^oneOf}}
1553
{{#isEnum}}
1654

1755
namespace {
@@ -159,6 +197,7 @@ void {{classname}}::unset{{name}}() {
159197
{{/isInherited}}
160198
{{/vars}}
161199
{{/isEnum}}
200+
{{/oneOf}}
162201
{{#modelNamespaceDeclarations}}
163202
}
164203
{{/modelNamespaceDeclarations}}

modules/openapi-generator/src/main/resources/cpp-libcurl/modelbase-header.mustache

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
#include <memory>
1919
#include <set>
2020
#include <string>
21+
#include <type_traits>
2122
#include <utility>
23+
#include <variant>
2224
#include <vector>
2325

2426
{{#modelNamespaceDeclarations}}
@@ -51,6 +53,11 @@ public:
5153
static nlohmann::json toJson(const std::set<T>& val);
5254
template<typename T>
5355
static nlohmann::json toJson(const std::map<std::string, T, std::less<>>& val);
56+
template<class T,
57+
std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::toJson)>, bool> = false>
58+
static nlohmann::json toJson(const T& val) {
59+
return val.toJson();
60+
}
5461

5562
static bool fromJson(const nlohmann::json& val, bool &);
5663
static bool fromJson(const nlohmann::json& val, float &);
@@ -61,6 +68,7 @@ public:
6168
static bool fromJson(const nlohmann::json& val, uint64_t &);
6269
static bool fromJson(const nlohmann::json& val, std::string &);
6370
static bool fromJson(const nlohmann::json& val, nlohmann::json &);
71+
static bool fromJson(const nlohmann::json& val, const std::monostate&);
6472
template<typename T>
6573
static bool fromJson(const nlohmann::json& val, std::shared_ptr<T>&);
6674
template<typename T>
@@ -69,6 +77,15 @@ public:
6977
static bool fromJson(const nlohmann::json& val, std::set<T> &);
7078
template<typename T>
7179
static bool fromJson(const nlohmann::json& val, std::map<std::string, T, std::less<>> &);
80+
template<class T,
81+
std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::fromJson)>, bool> = false>
82+
static bool fromJson(const nlohmann::json& val, T& outVal) {
83+
return outVal.fromJson(val);
84+
}
85+
template<size_t N, typename... Args>
86+
static bool fromJson(const nlohmann::json &val, std::variant<Args...> &);
87+
template<typename... Args>
88+
static bool fromJson(const nlohmann::json &val, std::variant<Args...> &);
7289

7390
private:
7491
bool m_IsSet{false};
@@ -168,6 +185,27 @@ bool ModelBase::fromJson(const nlohmann::json& val, std::map<std::string, T, std
168185
}
169186
return ok;
170187
}
188+
template<size_t N, typename... Args>
189+
bool ModelBase::fromJson([[maybe_unused]] const nlohmann::json &val,
190+
[[maybe_unused]] std::variant<Args...> &outVal) {
191+
if constexpr (N >= sizeof...(Args)) {
192+
return false;
193+
} else {
194+
std::variant_alternative_t<N, std::variant<Args...>> target;
195+
196+
if (!ModelBase::fromJson(val, target)) {
197+
return fromJson<N + 1>(val, outVal);
198+
}
199+
200+
outVal = std::move(target);
201+
return true;
202+
}
203+
}
204+
template<typename... Args>
205+
bool ModelBase::fromJson(const nlohmann::json &val, std::variant<Args...> &outVal) {
206+
/* Try each variant type in order until a successful conversion */
207+
return fromJson<0>(val, outVal);
208+
}
171209
{{#modelNamespaceDeclarations}}
172210
}
173211
{{/modelNamespaceDeclarations}}

modules/openapi-generator/src/main/resources/cpp-libcurl/modelbase-source.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ bool ModelBase::fromJson(const nlohmann::json& val, nlohmann::json & outVal) {
7272
outVal = val;
7373
return !val.is_null();
7474
}
75+
bool ModelBase::fromJson(const nlohmann::json& val, const std::monostate&) {
76+
return val.is_null();
77+
}
7578

7679
{{#modelNamespaceDeclarations}}
7780
}

samples/client/petstore/cpp/libcurl/include/CppLibcurlOpenAPIClient/ModelBase.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
#include <memory>
2929
#include <set>
3030
#include <string>
31+
#include <type_traits>
3132
#include <utility>
33+
#include <variant>
3234
#include <vector>
3335

3436
namespace org::openapitools::client::model {
@@ -59,6 +61,11 @@ class ModelBase {
5961
static nlohmann::json toJson(const std::set<T>& val);
6062
template<typename T>
6163
static nlohmann::json toJson(const std::map<std::string, T, std::less<>>& val);
64+
template<class T,
65+
std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::toJson)>, bool> = false>
66+
static nlohmann::json toJson(const T& val) {
67+
return val.toJson();
68+
}
6269

6370
static bool fromJson(const nlohmann::json& val, bool &);
6471
static bool fromJson(const nlohmann::json& val, float &);
@@ -69,6 +76,7 @@ class ModelBase {
6976
static bool fromJson(const nlohmann::json& val, uint64_t &);
7077
static bool fromJson(const nlohmann::json& val, std::string &);
7178
static bool fromJson(const nlohmann::json& val, nlohmann::json &);
79+
static bool fromJson(const nlohmann::json& val, const std::monostate&);
7280
template<typename T>
7381
static bool fromJson(const nlohmann::json& val, std::shared_ptr<T>&);
7482
template<typename T>
@@ -77,6 +85,15 @@ class ModelBase {
7785
static bool fromJson(const nlohmann::json& val, std::set<T> &);
7886
template<typename T>
7987
static bool fromJson(const nlohmann::json& val, std::map<std::string, T, std::less<>> &);
88+
template<class T,
89+
std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::fromJson)>, bool> = false>
90+
static bool fromJson(const nlohmann::json& val, T& outVal) {
91+
return outVal.fromJson(val);
92+
}
93+
template<size_t N, typename... Args>
94+
static bool fromJson(const nlohmann::json &val, std::variant<Args...> &);
95+
template<typename... Args>
96+
static bool fromJson(const nlohmann::json &val, std::variant<Args...> &);
8097

8198
private:
8299
bool m_IsSet{false};
@@ -176,6 +193,27 @@ bool ModelBase::fromJson(const nlohmann::json& val, std::map<std::string, T, std
176193
}
177194
return ok;
178195
}
196+
template<size_t N, typename... Args>
197+
bool ModelBase::fromJson([[maybe_unused]] const nlohmann::json &val,
198+
[[maybe_unused]] std::variant<Args...> &outVal) {
199+
if constexpr (N >= sizeof...(Args)) {
200+
return false;
201+
} else {
202+
std::variant_alternative_t<N, std::variant<Args...>> target;
203+
204+
if (!ModelBase::fromJson(val, target)) {
205+
return fromJson<N + 1>(val, outVal);
206+
}
207+
208+
outVal = std::move(target);
209+
return true;
210+
}
211+
}
212+
template<typename... Args>
213+
bool ModelBase::fromJson(const nlohmann::json &val, std::variant<Args...> &outVal) {
214+
/* Try each variant type in order until a successful conversion */
215+
return fromJson<0>(val, outVal);
216+
}
179217
}
180218

181219
#endif /* ORG_OPENAPITOOLS_CLIENT_MODEL_ModelBase_H_ */

samples/client/petstore/cpp/libcurl/src/ModelBase.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,8 @@ bool ModelBase::fromJson(const nlohmann::json& val, nlohmann::json & outVal) {
8080
outVal = val;
8181
return !val.is_null();
8282
}
83+
bool ModelBase::fromJson(const nlohmann::json& val, const std::monostate&) {
84+
return val.is_null();
85+
}
8386

8487
}

samples/client/petstore/cpp/libcurl/src/model/Category.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
namespace org::openapitools::client::model {
1616

17-
1817
nlohmann::json Category::toJson() const {
1918
nlohmann::json val = nlohmann::json::object();
2019
if (m_IdIsSet) {

samples/client/petstore/cpp/libcurl/src/model/Order.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
namespace org::openapitools::client::model {
1616

17-
1817
nlohmann::json Order::toJson() const {
1918
nlohmann::json val = nlohmann::json::object();
2019
if (m_IdIsSet) {

samples/client/petstore/cpp/libcurl/src/model/Pet.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
namespace org::openapitools::client::model {
1616

17-
1817
nlohmann::json Pet::toJson() const {
1918
nlohmann::json val = nlohmann::json::object();
2019
if (m_IdIsSet) {

0 commit comments

Comments
 (0)