diff options
Diffstat (limited to 'lib/configuration/configuration.h')
-rw-r--r-- | lib/configuration/configuration.h | 136 |
1 files changed, 46 insertions, 90 deletions
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h index 40da50e..bc8f52e 100644 --- a/lib/configuration/configuration.h +++ b/lib/configuration/configuration.h @@ -9,121 +9,77 @@ #ifndef SMOLBOTE_CONFIGURATION_H #define SMOLBOTE_CONFIGURATION_H -#include <QAction> -#include <QString> -#include <QStringList> -#include <QVariant> -#include <boost/program_options.hpp> #include <optional> #include <string> #include <vector> +#include <unordered_map> +#include <variant> +#include <initializer_list> +#include <memory> +#include <QAction> +#include <QString> -class Configuration : public QObject +typedef std::variant<std::string, int, bool> conf_value_t; + +class [[clang::consumable(unconsumed)]] Configuration : private std::unordered_map<std::string, conf_value_t> { - Q_OBJECT public: - explicit Configuration(int argc, char** argv, const std::string &path, QObject *parent = nullptr); + [[clang::return_typestate(unconsumed)]] + explicit Configuration(); + + [[clang::return_typestate(unconsumed)]] + explicit Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept; + + explicit Configuration(Configuration &&other [[clang::param_typestate(unconsumed)]]) = default; + ~Configuration() = default; - bool exists(const char *path) - { - return vm.count(path) ? true : false; - } + [[clang::callable_when(unconsumed)]] + void read(std::basic_istream<char> &input); template <typename T> - std::optional<T> value(const char *path) const + [[clang::callable_when(unconsumed)]] std::optional<T> value(const char *path) const { - // if setting doesn't exist, we crash - // in debug builds, check if setting exists - - if(vm.count(path) == 0) { + if(use_global) + return instance()->value<T>(path); + + if(this->count(path) == 0) { return std::nullopt; } - // path is guaranteed to exist, so using vm[path] is safe - - if constexpr(std::is_same_v<T, QStringList>) { - QStringList r; - for(const std::string &item : vm[path].as<std::vector<std::string>>()) { - r.append(QString::fromStdString(item)); - } - return std::optional<QStringList>(r); - - } else if constexpr(std::is_same_v<T, std::string> || std::is_same_v<T, QString>) { - - if(vm[path].value().type() == typeid(int)) { - if constexpr(std::is_same_v<T, std::string>) - return std::optional<std::string>(std::to_string(vm[path].as<int>())); - else if constexpr(std::is_same_v<T, QString>) - return std::optional<QString>(QString::number(vm[path].as<int>())); - } - - if(vm[path].value().type() == typeid(bool)) { - return std::optional<T>(vm[path].as<bool>() ? "true" : "false"); - } - - std::string r = vm[path].as<std::string>(); + // path is guaranteed to exist + const auto value = at(path); - // check if it's a path - if(r.front() == '~') { + if constexpr(std::is_same_v<T, QString> || std::is_same_v<T, std::string>) { + auto r = std::get<std::string>(value); + if(r.front() == '~') r.replace(0, 1, m_homePath); - } - if constexpr(std::is_same_v<T, std::string>) - return std::optional<std::string>(r); - else if constexpr(std::is_same_v<T, QString>) - return std::optional<QString>(QString::fromStdString(r)); + if constexpr(std::is_same_v<T, QString>) + return std::make_optional(QString::fromStdString(r)); + else + return std::make_optional(r); - } else - return std::optional<T>(vm[path].as<T>()); - } - - template <typename T> - void setValue(const char *path, const T &value) - { - if(vm.count(path) == 0) { - qWarning("value(%s) does not exist", path); - } - - vm.at(path).value() = value; - - emit settingChanged(path, value); - } + } else if constexpr(std::is_same_v<T, QStringList>) { + return std::make_optional(QString::fromStdString(std::get<std::string>(value)).split(';')); - void setShortcut(QAction *action, const char *name) const - { - Q_CHECK_PTR(action); - - const auto shortcutText = this->value<QString>(name); - if(shortcutText) { - const QString tooltip = action->toolTip(); - action->setShortcut(QKeySequence::fromString(shortcutText.value())); - action->setToolTip(QString("%1 (%2)").arg(tooltip, shortcutText.value())); - - connect(this, &Configuration::settingChanged, action, [=](const std::string &path, const QString &value) { - if(path == name) { - action->setShortcut(QKeySequence::fromString(value)); - action->setToolTip(QString("%1 (%2)").arg(tooltip, value)); - } - }); - } - } - - QHash<QString, QString> section(const std::string &prefix) const; - const boost::program_options::options_description& description() const - { - return configuration_desc; - } + } else if (std::holds_alternative<T>(value)) { + return std::optional<T>(std::get<T>(value)); + } else + return std::nullopt; + + } // std::optional<T> value(path) const -signals: - void settingChanged(const std::string &path, const QString &value); + static void move_global(std::unique_ptr<Configuration> &&conf); private: - boost::program_options::options_description configuration_desc; - boost::program_options::variables_map vm; + static Configuration *instance(); const std::string m_homePath; + const bool use_global = false; }; +void setShortcut(QAction *action, const char *name); + #endif // SMOLBOTE_CONFIGURATION_H |