aboutsummaryrefslogtreecommitdiff
path: root/lib/configuration/configuration.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/configuration/configuration.h')
-rw-r--r--lib/configuration/configuration.h136
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