Source code

Revision control

Copy as Markdown

/**
* Qt6 Common library
*
* Copyright (C) 2026 The Qt Company Ltd.
* SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit the class manually.
*/
#include "qoaihelpers.h"
#include <QtCore/QJsonParseError>
#include <limits>
#include <type_traits>
QT_BEGIN_NAMESPACE
namespace QtOpenApiCommon {
using namespace Qt::StringLiterals;
class QOAISerializerSettings {
public:
struct CustomDateTimeFormat{
bool isStringSet = false;
QString formatString;
bool isEnumSet = false;
Qt::DateFormat formatEnum;
};
static CustomDateTimeFormat getCustomDateTimeFormat()
{
return getInstance()->customDateTimeFormat;
}
static void setDateTimeFormatString(const QString &dtFormat)
{
getInstance()->customDateTimeFormat.isStringSet = true;
getInstance()->customDateTimeFormat.isEnumSet = false;
getInstance()->customDateTimeFormat.formatString = dtFormat;
}
static void setDateTimeFormatEnum(const Qt::DateFormat &dtFormat)
{
getInstance()->customDateTimeFormat.isEnumSet = true;
getInstance()->customDateTimeFormat.isStringSet = false;
getInstance()->customDateTimeFormat.formatEnum = dtFormat;
}
static QOAISerializerSettings *getInstance()
{
if (instance == nullptr) {
instance = new QOAISerializerSettings();
}
return instance;
}
private:
explicit QOAISerializerSettings()
{
instance = this;
customDateTimeFormat.isStringSet = false;
customDateTimeFormat.isEnumSet = false;
}
static QOAISerializerSettings *instance;
CustomDateTimeFormat customDateTimeFormat;
};
QOAISerializerSettings * QOAISerializerSettings::instance = nullptr;
static bool fromStringValue(const QString &inStr, QDateTime &value)
{
if (inStr.isEmpty())
return false;
QDateTime dateTime;
if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet)
dateTime = QDateTime::fromString(inStr, QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatString);
else if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet)
dateTime = QDateTime::fromString(inStr, QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum);
else
dateTime = QDateTime::fromString(inStr, Qt::ISODate);
const bool isValid = dateTime.isValid();
if (isValid)
value = dateTime;
return isValid;
}
static bool fromStringValue(const QString &inStr, QDate &value)
{
if (inStr.isEmpty())
return false;
const auto date = QDate::fromString(inStr, Qt::DateFormat::ISODate);
const bool isValid = date.isValid();
if (isValid)
value = date;
return isValid;
}
bool setDateTimeFormat(const QString &dateTimeFormat)
{
bool success = false;
auto dt = QDateTime::fromString(QDateTime::currentDateTime().toString(dateTimeFormat), dateTimeFormat);
if (dt.isValid()) {
success = true;
QOAISerializerSettings::setDateTimeFormatString(dateTimeFormat);
}
return success;
}
bool setDateTimeFormat(const Qt::DateFormat &dateTimeFormat)
{
bool success = false;
auto dt = QDateTime::fromString(QDateTime::currentDateTime().toString(dateTimeFormat), dateTimeFormat);
if (dt.isValid()) {
success = true;
QOAISerializerSettings::setDateTimeFormatEnum(dateTimeFormat);
}
return success;
}
QString toStringValue(const QVariant &value)
{
return value.toString();
}
QString toStringValue(const QString &value)
{
return value;
}
QString toStringValue(const QDateTime &value)
{
if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
return value.toString(QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatString);
}
if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
return value.toString(QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum);
}
// ISO 8601
return value.toString(Qt::ISODate);
}
QString toStringValue(const QByteArray &value)
{
return QString::fromUtf8(value);
}
QString toStringValue(const QDate &value)
{
// ISO 8601
return value.toString(Qt::DateFormat::ISODate);
}
QString toStringValue(qint32 value)
{
return QString::number(value);
}
QString toStringValue(qint64 value)
{
return QString::number(value);
}
QString toStringValue(bool value)
{
return QString(value ? "true"_L1 : "false"_L1);
}
QString toStringValue(float value)
{
return toStringValue(static_cast<double>(value));
}
QString toStringValue(double value)
{
return QString::number(value, 'g', QLocale::FloatingPointShortest);
}
QString toStringValue(const QOAIObject &value)
{
return value.asJson();
}
QString toStringValue(const QOAIEnum &value)
{
return value.asJson();
}
QString toStringValue(const QOAIHttpFileElement &value)
{
return value.asJson();
}
QJsonValue toJsonValue(const QString &value)
{
return QJsonValue(value);
}
QJsonValue toJsonValue(const QDateTime &value)
{
if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
return QJsonValue(value.toString(QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatString));
}
if (QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
return QJsonValue(value.toString(QOAISerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum));
}
// ISO 8601
return QJsonValue(value.toString(Qt::ISODate));
}
QJsonValue toJsonValue(const QByteArray &value)
{
return QJsonValue(QString::fromUtf8(value.toBase64()));
}
QJsonValue toJsonValue(const QDate &value)
{
return QJsonValue(value.toString(Qt::ISODate));
}
QJsonValue toJsonValue(qint32 value)
{
return QJsonValue(value);
}
QJsonValue toJsonValue(qint64 value)
{
return QJsonValue(value);
}
QJsonValue toJsonValue(bool value)
{
return QJsonValue(value);
}
QJsonValue toJsonValue(float value)
{
return QJsonValue(static_cast<double>(value));
}
QJsonValue toJsonValue(double value)
{
return QJsonValue(value);
}
QJsonValue toJsonValue(const QOAIObject &value)
{
return value.asJsonValue();
}
QJsonValue toJsonValue(const QOAIEnum &value)
{
return value.asJsonValue();
}
QJsonValue toJsonValue(const QOAIHttpFileElement &value)
{
return value.asJsonValue();
}
QJsonValue toJsonValue(const QJsonValue &value)
{
return value;
}
bool fromByteArray(const QByteArray &input, QString &value)
{
value = QString::fromUtf8(input);
return true;
}
bool fromByteArray(const QByteArray &input, QDateTime &value)
{
if (input.isEmpty())
return false;
const QString inStr = QString::fromUtf8(input);
return fromStringValue(inStr, value);
}
bool fromByteArray(const QByteArray &input, QByteArray &value)
{
value = input;
return true;
}
bool fromByteArray(const QByteArray &input, QDate &value)
{
if (input.isEmpty())
return false;
const QString inStr = QString::fromUtf8(input);
return fromStringValue(inStr, value);
}
bool fromByteArray(const QByteArray &input, qint32 &value)
{
bool ok = false;
const qint32 parsed = input.toInt(&ok);
if (ok)
value = parsed;
return ok;
}
bool fromByteArray(const QByteArray &input, qint64 &value)
{
bool ok = false;
const qint64 parsed = input.toLongLong(&ok);
if (ok)
value = parsed;
return ok;
}
bool fromByteArray(const QByteArray &input, bool &value)
{
if (input == "true") {
value = true;
return true;
}
if (input == "false") {
value = false;
return true;
}
return false;
}
bool fromByteArray(const QByteArray &input, float &value)
{
bool ok = false;
const float parsed = input.toFloat(&ok);
// JSON spec does not allow NaN or Infinity as numeric values.
if (ok && !qIsNaN(parsed) && !qIsInf(parsed))
value = parsed;
else
ok = false;
return ok;
}
bool fromByteArray(const QByteArray &input, double &value)
{
bool ok = false;
const double parsed = input.toDouble(&ok);
// JSON spec does not allow NaN or Infinity as numeric values.
if (ok && !qIsNaN(parsed) && !qIsInf(parsed))
value = parsed;
else
ok = false;
return ok;
}
bool fromByteArray(const QByteArray &input, QOAIObject &value)
{
QJsonParseError err;
const auto json = QJsonValue::fromJson(input, &err);
if (err.error != QJsonParseError::NoError || !json.isObject())
return false;
value.fromJsonValue(json);
return true;
}
bool fromByteArray(const QByteArray &input, QOAIEnum &value)
{
// TODO: rework QOAIEnum to take QBA?
value.fromJson(QString::fromUtf8(input));
return value.isValid();
}
bool fromByteArray(const QByteArray &input, QOAIHttpFileElement &value)
{
return value.saveToLocalFile(input);
}
bool fromJsonValue(QString &value, const QJsonValue &jval)
{
if (jval.isString()) {
value = jval.toString();
return true;
}
return false;
}
bool fromJsonValue(QDateTime &value, const QJsonValue &jval)
{
if (!jval.isString())
return false;
const QString inStr = jval.toString();
return fromStringValue(inStr, value);
}
bool fromJsonValue(QByteArray &value, const QJsonValue &jval)
{
bool ok = true;
if (!jval.isUndefined() && !jval.isNull() && jval.isString()) {
value = QByteArray::fromBase64(QByteArray::fromStdString(jval.toString().toStdString()));
ok = value.size() > 0;
} else {
ok = false;
}
return ok;
}
bool fromJsonValue(QDate &value, const QJsonValue &jval)
{
if (!jval.isString())
return false;
const QString inStr = jval.toString();
return fromStringValue(inStr, value);
}
// Template helper for signed integer types
template <typename IntType,
std::enable_if_t<
std::conjunction_v<std::is_integral<IntType>,
std::is_signed<IntType>>,
bool> = true>
static bool fromJsonValueIntegral(IntType &value, const QJsonValue &jval)
{
if (!jval.isDouble())
return false;
const qint64 intVal = jval.toInteger();
// Roundtrip to catch actual 0 value
if (static_cast<double>(intVal) != jval.toDouble())
return false;
// Range check
if (intVal < std::numeric_limits<IntType>::min()
|| intVal > std::numeric_limits<IntType>::max()) {
return false;
}
value = static_cast<IntType>(intVal);
return true;
}
bool fromJsonValue(qint32 &value, const QJsonValue &jval)
{
return fromJsonValueIntegral(value, jval);
}
bool fromJsonValue(qint64 &value, const QJsonValue &jval)
{
return fromJsonValueIntegral(value, jval);
}
bool fromJsonValue(bool &value, const QJsonValue &jval)
{
bool ok = true;
if (jval.isBool()) {
value = jval.toVariant().toBool();
} else {
ok = false;
}
return ok;
}
bool fromJsonValue(float &value, const QJsonValue &jval)
{
bool ok = true;
if (jval.isDouble()) {
value = static_cast<float>(jval.toVariant().toDouble());
} else {
ok = false;
}
return ok;
}
bool fromJsonValue(double &value, const QJsonValue &jval)
{
bool ok = true;
if (jval.isDouble()) {
value = jval.toVariant().toDouble();
} else {
ok = false;
}
return ok;
}
bool fromJsonValue(QOAIObject &value, const QJsonValue &jval)
{
bool ok = true;
if (jval.isObject()) {
value.fromJsonValue(jval);
ok = value.isValid();
} else {
ok = false;
}
return ok;
}
bool fromJsonValue(QOAIEnum &value, const QJsonValue &jval)
{
value.fromJsonValue(jval);
return true;
}
bool fromJsonValue(QOAIHttpFileElement &value, const QJsonValue &jval)
{
return value.fromJsonValue(jval);
}
bool fromJsonValue(QJsonValue &value, const QJsonValue &jval)
{
value = jval;
return true;
}
// Specialization for QString
bool isPrimitiveType(const QString&)
{
return true;
}
// Specialization for QByteArray
bool isPrimitiveType(const QByteArray&)
{
return true;
}
QString convertJsonValueToString(const QJsonValue &jsonValue)
{
if (jsonValue.isArray()) {
return QString::fromUtf8(QJsonDocument(jsonValue.toArray()).toJson(QJsonDocument::Compact));
}
if (jsonValue.isObject()) {
return QString::fromUtf8(QJsonDocument(jsonValue.toObject()).toJson(QJsonDocument::Compact));
}
return jsonValue.toVariant().toString();
}
// Param prefix - the first parameter related symbol in a serialization string.
QString getParamStylePrefix(std::string_view style)
{
if (style == "matrix") {
return ";"_L1;
} else if (style == "label") {
return "."_L1;
} else if (style == "form") {
return "?"_L1;
} else if (style == "simple") {
return ""_L1;
} else if (style == "spaceDelimited") {
return "?"_L1;
} else if (style == "pipeDelimited") {
return "?"_L1;
} else if (style == "deepObject") {
return "?"_L1;
}
Q_UNREACHABLE_RETURN(QString());
}
QString getParamStyleSuffix(std::string_view style, const QString &name, SerializationFlags flags)
{
const bool isExplode = flags.testFlag(SerializationFlag::Explode);
const bool isObject = flags.testFlag(SerializationFlag::Object);
if (style == "matrix") {
// for undefined cases "=" will be deleted on serialization.
return (isExplode && isObject) ? QString() : name + QString::fromLatin1("=");
} else if (style == "label") {
return ""_L1;
} else if (style == "form") {
return (isExplode && isObject) ? QString() : name + QString::fromLatin1("=");
} else if (style == "simple") {
return ""_L1;
} else if (style == "spaceDelimited") {
return name + "="_L1;
} else if (style == "pipeDelimited") {
return name + "="_L1;
} else if (style == "deepObject") {
return name;
}
Q_UNREACHABLE_RETURN(QString());
}
QString getParamStyleDelimiter(std::string_view style, SerializationFlags flags)
{
const bool isExplode = flags.testFlag(SerializationFlag::Explode);
if (style == "matrix") {
return (isExplode) ? ";"_L1 : ","_L1;
} else if (style == "label") {
return (isExplode) ? "."_L1 : ","_L1;
} else if (style == "form") {
return (isExplode) ? "&"_L1 : ","_L1;
} else if (style == "simple") {
return ","_L1;
} else if (style == "spaceDelimited") {
return QString::fromLatin1(QUrl::toPercentEncoding(" "_L1));
} else if (style == "pipeDelimited") {
return QString::fromLatin1(QUrl::toPercentEncoding("|"_L1));
} else if (style == "deepObject") {
return "&"_L1;
}
Q_UNREACHABLE_RETURN(QString());
}
QString getParamStyleAssignOperator(std::string_view style, SerializationFlags flags)
{
const bool isExplode = flags.testFlag(SerializationFlag::Explode);
const bool isObject = flags.testFlag(SerializationFlag::Object);
if (!isObject)
return ""_L1;
if (style == "matrix") {
return (isExplode) ? "="_L1 : ","_L1;
} else if (style == "label") {
return (isExplode) ? "="_L1 : ","_L1;
} else if (style == "form") {
return (isExplode) ? "="_L1 : ","_L1;
} else if (style == "simple") {
return (isExplode) ? "="_L1 : ","_L1;
} else if (style == "spaceDelimited") {
return QString::fromLatin1(QUrl::toPercentEncoding(" "_L1));
} else if (style == "pipeDelimited") {
return QString::fromLatin1(QUrl::toPercentEncoding("|"_L1));
} else if (style == "deepObject") {
return "="_L1;
}
Q_UNREACHABLE_RETURN(QString());
}
QString serializeJsonValue(const QJsonValue &value, const SerializationOptions &opts)
{
const bool percentEncode = opts.flags.testFlag(SerializationFlag::NeedPercentEncoding);
QString paramString;
switch(value.type()) {
case QJsonValue::String:
case QJsonValue::Bool:
case QJsonValue::Double:
{
paramString = opts.suffix;
const QString stringValue = toStringValue(value.toVariant());
paramString.append(percentEncode ? QString::fromLatin1(QUrl::toPercentEncoding(stringValue))
: stringValue);
} break;
case QJsonValue::Array:
{
const QVariantList array = value.toArray().toVariantList();
paramString = serializeArrayValue(array, opts);
} break;
case QJsonValue::Object:
{
QVariantMap map = value.toObject().toVariantMap();
if (map.size() > 0) {
if (opts.style == "deepObject") {
qsizetype index = 0;
for (const auto &[key, val] : map.asKeyValueRange()) {
if (index > 0)
paramString.append(opts.delimiter);
if (percentEncode) {
paramString.append(opts.suffix
+ QString::fromLatin1(QUrl::toPercentEncoding(u"[%1]"_s.arg(key)))
+ opts.assignOperator
+ QString::fromLatin1(QUrl::toPercentEncoding(toStringValue(val))));
} else {
paramString.append(opts.suffix + u"[%1]"_s.arg(key)
+ opts.assignOperator + toStringValue(val));
}
++index;
}
} else {
paramString = opts.suffix;
paramString.append(serializeMapValue(map, opts));
}
} else {
qWarning() << "Serialized QJsonValue::Object is empty!";
}
} break;
case QJsonValue::Null:
case QJsonValue::Undefined:
{
paramString = opts.suffix;
qWarning() << "Parameter serialization is not supported for the value:" << value;
} break;
}
return paramString;
}
} // namespace QtOpenApiCommon
QT_END_NAMESPACE