From bfce96bf265fbb33ae7105dc817e9c379747a573 Mon Sep 17 00:00:00 2001 From: Michael Cramer Date: Fri, 23 Jan 2026 11:19:39 +0100 Subject: [PATCH] add support for oneOf relates to #6378 --- .../cpp-qt-client/model-body.mustache | 5 +- .../cpp-qt-client/model-header.mustache | 5 +- .../cpp-qt-client/model-oneof-body.mustache | 142 ++++++++++++++++++ .../cpp-qt-client/model-oneof.mustache | 69 +++++++++ 4 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof-body.mustache create mode 100644 modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof.mustache diff --git a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-body.mustache b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-body.mustache index 28e3f674e41a..0ff7fb654a9c 100644 --- a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-body.mustache +++ b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-body.mustache @@ -1,10 +1,11 @@ -{{>licenseInfo}}{{#models}}{{#model}} +{{>licenseInfo}}{{#models}}{{#model}}{{#discriminator}}{{>model-oneof-body}}{{/discriminator}}{{^discriminator}} #include "{{classname}}.h" #include #include #include #include +#include #include "{{prefix}}Helpers.h" @@ -160,5 +161,5 @@ bool {{classname}}::isValid() const { {{#cppNamespaceDeclarations}} } // namespace {{this}} {{/cppNamespaceDeclarations}} -{{/model}} +{{/discriminator}}{{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-header.mustache b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-header.mustache index 8b4a1a6d4d22..7120fd3df958 100644 --- a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-header.mustache +++ b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-header.mustache @@ -1,5 +1,5 @@ {{>licenseInfo}} -{{#models}}{{#model}}/* +{{#models}}{{#model}}{{#discriminator}}{{>model-oneof}}{{/discriminator}}{{^discriminator}}/* * {{classname}}.h * * {{description}} @@ -10,6 +10,7 @@ #include +{{/discriminator}} {{/model}}{{/models}}{{#imports}}{{{import}}} {{/imports}} @@ -18,6 +19,7 @@ {{#models}} {{#model}} +{{^discriminator}} {{#cppNamespaceDeclarations}} namespace {{this}} { {{/cppNamespaceDeclarations}} @@ -76,5 +78,6 @@ private: Q_DECLARE_METATYPE({{#cppNamespaceDeclarations}}{{this}}::{{/cppNamespaceDeclarations}}{{classname}}) #endif // {{classname}}_H +{{/discriminator}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof-body.mustache b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof-body.mustache new file mode 100644 index 000000000000..4a350a5521b5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof-body.mustache @@ -0,0 +1,142 @@ +#include "{{classname}}.h" + +#include +#include +#include +#include +#include +#include +#include + +{{#discriminator}} +{{#mappedModels}} +#include "{{modelName}}.h" +{{/mappedModels}} +{{/discriminator}} + +{{#cppNamespaceDeclarations}} +namespace {{this}} { +{{/cppNamespaceDeclarations}} + +{{classname}}::{{classname}}() { + this->initializeModel(); +} + +{{classname}}::{{classname}}(QString json) { + this->initializeModel(); + this->fromJson(json); +} + +{{classname}}::~{{classname}}() {} + +void {{classname}}::initializeModel() { + m_actualInstance = std::monostate{}; + m_discriminatorValue = QString(); +} + +void {{classname}}::fromJson(QString jsonString) { + QByteArray array(jsonString.toStdString().c_str()); + QJsonDocument doc = QJsonDocument::fromJson(array); + QJsonObject jsonObject = doc.object(); + this->fromJsonObject(jsonObject); +} + +void {{classname}}::fromJsonObject(QJsonObject json) { +{{#discriminator}} + m_discriminatorValue = json["{{propertyName}}"].toString(); +{{/discriminator}} + +{{#discriminator}} +{{#mappedModels}} + if (m_discriminatorValue == "{{mappingName}}") { + auto instance = std::make_shared<{{modelName}}>(); + instance->fromJsonObject(json); + m_actualInstance = instance; + return; + } +{{/mappedModels}} +{{/discriminator}} + + qWarning() << "{{classname}}: Unknown discriminator value '" << m_discriminatorValue << "'"; +} + +QString {{classname}}::asJson() const { + return std::visit([](const auto& value) -> QString { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return QString(); + } else { + return value->asJson(); + } + }, m_actualInstance); +} + +QJsonObject {{classname}}::asJsonObject() const { + return std::visit([this](const auto& value) -> QJsonObject { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return QJsonObject(); + } else { + QJsonObject obj = value->asJsonObject(); +{{#discriminator}} + if (!m_discriminatorValue.isEmpty()) { + obj.insert(QString("{{propertyName}}"), QJsonValue(m_discriminatorValue)); + } +{{/discriminator}} + return obj; + } + }, m_actualInstance); +} + +bool {{classname}}::isSet() const { + return !std::holds_alternative(m_actualInstance) && !m_discriminatorValue.isEmpty(); +} + + +bool {{classname}}::isValid() const { + return std::visit([](const auto& value) -> bool { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return false; + } else { + return value->isValid(); + } + }, m_actualInstance); +} + +void {{classname}}::setValue(const {{classname}}::VariantType &value) { + m_actualInstance = value; + + // Determine discriminator value by visiting the variant + std::visit([this](const auto& v) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + m_discriminatorValue = QString(); + } else { +{{#discriminator}} +{{#mappedModels}} + if constexpr (std::is_same_v>) { + m_discriminatorValue = "{{mappingName}}"; + } +{{/mappedModels}} +{{/discriminator}} + } + }, value); +} + +{{#discriminator}} +{{#mappedModels}} +bool {{classname}}::is{{modelName}}() const { + return std::holds_alternative>(m_actualInstance); +} + +std::shared_ptr<{{modelName}}> {{classname}}::as{{modelName}}() const { + auto ptr = std::get_if>(const_cast(&m_actualInstance)); + return ptr ? *ptr : nullptr; +} +{{/mappedModels}} +{{/discriminator}} + +{{#cppNamespaceDeclarations}} +} // namespace {{this}} +{{/cppNamespaceDeclarations}} diff --git a/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof.mustache b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof.mustache new file mode 100644 index 000000000000..2fe54ba2a03a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-qt-client/model-oneof.mustache @@ -0,0 +1,69 @@ +/* + * {{classname}}.h - OneOf Model + * + * {{description}} + */ + +#ifndef {{classname}}_H +#define {{classname}}_H + +#include +#include +#include +#include +#include + +#include "{{prefix}}Enum.h" +#include "{{prefix}}Object.h" + +{{#cppNamespaceDeclarations}} +namespace {{this}} { +{{/cppNamespaceDeclarations}} + +{{#discriminator}} +{{#mappedModels}} +class {{modelName}}; +{{/mappedModels}} +{{/discriminator}} + +class {{classname}} : public {{prefix}}Object { +public: + {{classname}}(); + explicit {{classname}}(QString json); + ~{{classname}}() override; + + QString asJson() const override; + QJsonObject asJsonObject() const override; + void fromJsonObject(QJsonObject json) override; + void fromJson(QString jsonString) override; + + virtual bool isSet() const override; + virtual bool isValid() const override; + +{{#discriminator}} + typedef std::variant{{/mappedModels}}> VariantType; + void setValue(const VariantType &value); +{{/discriminator}} + +{{#discriminator}} +{{#mappedModels}} + bool is{{modelName}}() const; + std::shared_ptr<{{modelName}}> as{{modelName}}() const; +{{/mappedModels}} +{{/discriminator}} + +private: + void initializeModel(); +{{#discriminator}} + VariantType m_actualInstance; +{{/discriminator}} + QString m_discriminatorValue; +}; + +{{#cppNamespaceDeclarations}} +} // namespace {{this}} +{{/cppNamespaceDeclarations}} + +Q_DECLARE_METATYPE({{#cppNamespaceDeclarations}}{{this}}::{{/cppNamespaceDeclarations}}{{classname}}) + +#endif // {{classname}}_H