#include "common.hpp" #include "node.hpp" using Qt::StringLiterals::operator""_s; namespace ZShell::settings { Q_LOGGING_CATEGORY(lcSettings, "zshell.settings", QtInfoMsg) WriteScope::WriteScope(Node* node, WriteOrigin origin) : m_root(node->rootNode()), m_previous(m_root->m_writeOrigin) { m_root->m_writeOrigin = origin; } WriteScope::~WriteScope() { m_root->m_writeOrigin = m_previous; } InternalRead::InternalRead(Node* node) : m_root(node->rootNode()), m_previous(m_root->m_internalRead) { m_root->m_internalRead = true; } InternalRead::~InternalRead() { m_root->m_internalRead = m_previous; } QString DiagnosticType::toString(Type t) { switch (t) { case UnknownOption: return u"UnknownOption"_s; case GlobalOption: return u"GlobalOption"_s; case TypeMismatch: return u"TypeMismatch"_s; case InvalidValue: return u"InvalidValue"_s; } Q_UNREACHABLE_RETURN(QString()); } namespace { QString expectedStr(ExpectedType expected) { switch (expected) { case ExpectedType::Bool: return QStringLiteral("a boolean"); case ExpectedType::Int: return QStringLiteral("an integer"); case ExpectedType::Real: return QStringLiteral("a number"); case ExpectedType::String: return QStringLiteral("a string"); case ExpectedType::Array: return QStringLiteral("an array"); case ExpectedType::Object: return QStringLiteral("an object"); } Q_UNREACHABLE_RETURN(QString()); } QString receivedStr(const QJsonValue& value) { switch (value.type()) { case QJsonValue::Null: return QStringLiteral("null"); case QJsonValue::Bool: return QStringLiteral("a boolean"); case QJsonValue::Double: return QStringLiteral("a number"); case QJsonValue::String: return QStringLiteral("a string"); case QJsonValue::Array: return QStringLiteral("an array"); case QJsonValue::Object: return QStringLiteral("an object"); default: return QStringLiteral("nothing"); } } QString mismatchStr( const QList& expected, const QJsonValue& value) { QStringList types; types.reserve(expected.size()); for (const auto type : expected) types << expectedStr(type); const auto received = receivedStr(value); switch (expected.size()) { case 2: return QStringLiteral("Expected %1 or %2, got %3") .arg(types[0], types[1], received); case 3: return QStringLiteral("Expected %1, %2 or %3, got %4") .arg(types[0], types[1], types[2], received); case 4: return QStringLiteral("Expected one of: %1, %2, %3, %4; got %5") .arg(types[0], types[1], types[2], types[3], received); default: // The bounds are checked in macros.hpp `unionType<...T>` Q_UNREACHABLE_RETURN(QString()); } } } // namespace Diagnostic Diagnostic::mismatch( ExpectedType expected, const QJsonValue& value, const QString& option) { return { .type = DiagnosticType::TypeMismatch, .option = option, .message = QStringLiteral("Expected %1, got %2") .arg(expectedStr(expected), receivedStr(value)), }; } Diagnostic Diagnostic::mismatch( const QList& expected, const QJsonValue& value, const QString& option) { return { .type = DiagnosticType::TypeMismatch, .option = option, .message = mismatchStr(expected, value), }; } } // namespace ZShell::settings