aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2019-11-09 21:05:07 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2019-11-09 21:05:07 +0200
commiteb311838538b80fb3280aa9ab5b57abc22925926 (patch)
tree71a705fb9594fd4b169aea175047f91287b1ba18 /lib
parentFix manpages not disabled when disabled by meson (diff)
downloadsmolbote-eb311838538b80fb3280aa9ab5b57abc22925926.tar.xz
Add configuration subcommand
--dump: Write current configuration to stdout and exit
Diffstat (limited to 'lib')
-rw-r--r--lib/configuration/configuration.cpp44
-rw-r--r--lib/configuration/configuration.h51
2 files changed, 63 insertions, 32 deletions
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index bd7700c..34e84af 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -7,11 +7,11 @@
*/
#include "configuration.h"
-#include <sstream>
+#include <QStandardPaths>
#include <algorithm>
-#include <stdexcept>
#include <iostream>
-#include <QStandardPaths>
+#include <sstream>
+#include <stdexcept>
static std::unique_ptr<Configuration> s_conf;
@@ -21,7 +21,6 @@ inline void strip(std::string &value)
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
}
-
Configuration::Configuration()
: use_global(true)
{
@@ -32,9 +31,9 @@ Configuration::Configuration()
Configuration::Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept
: m_homePath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString())
{
- for(const auto &i : l) {
- insert_or_assign(i.first, i.second);
- }
+ for(const auto &i : l) {
+ insert_or_assign(i.first, i.second);
+ }
}
void Configuration::read(std::basic_istream<char> &input)
@@ -69,18 +68,16 @@ void Configuration::read(std::basic_istream<char> &input)
} else if(std::holds_alternative<bool>(v)) {
at(key) = (value == "true");
}
-
}
}
}
-
void Configuration::move_global(std::unique_ptr<Configuration> &&conf)
{
s_conf = std::move(conf);
}
-Configuration* Configuration::instance()
+Configuration *Configuration::instance()
{
return s_conf.get();
}
@@ -101,3 +98,30 @@ void setShortcut(QAction *action, const char *name)
}
#endif
}
+
+std::ostream &operator<<(std::ostream &out, const Configuration &obj)
+{
+ // unordered_map is, well, unordered, so grab the keys and sort them before printing them
+ std::vector<std::string> keys;
+
+ if(obj.use_global) {
+ if(!s_conf)
+ throw new std::runtime_error("Trying to use default Configuration, but none has been set!");
+
+ for(const auto &pair : *s_conf)
+ keys.emplace_back(pair.first);
+ } else {
+ for(const auto &pair : obj)
+ out << pair.first << "\n";
+ }
+ std::sort(keys.begin(), keys.end());
+
+ for(const auto &key : keys) {
+ if(obj.use_global)
+ out << key << "=" << s_conf->value<std::string>(key.c_str()).value() << "\n";
+ else
+ out << key << "=" << obj.value<std::string>(key.c_str()).value() << "\n";
+ }
+
+ return out;
+}
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h
index b77685a..4459dd0 100644
--- a/lib/configuration/configuration.h
+++ b/lib/configuration/configuration.h
@@ -9,21 +9,21 @@
#ifndef SMOLBOTE_CONFIGURATION_H
#define SMOLBOTE_CONFIGURATION_H
+#include <QAction>
+#include <QString>
+#include <initializer_list>
+#include <memory>
#include <optional>
#include <string>
-#include <vector>
#include <unordered_map>
#include <variant>
-#include <initializer_list>
-#include <memory>
-#include <QAction>
-#include <QString>
+#include <vector>
-#if defined (__clang__)
-#define consumable(X) [[clang::consumable(X)]]
-#define return_typestate(X) [[clang::return_typestate(X)]]
-#define callable_when(X) [[clang::callable_when(X)]]
-#define param_typestate(X) [[clang::param_typestate(X)]]
+#if defined(__clang__)
+#define consumable(X) [[clang::consumable(X)]]
+#define return_typestate(X) [[clang::return_typestate(X)]]
+#define callable_when(X) [[clang::callable_when(X)]]
+#define param_typestate(X) [[clang::param_typestate(X)]]
#else
#define consumable(X)
#define return_typestate(X)
@@ -35,27 +35,25 @@ typedef std::variant<std::string, int, bool> conf_value_t;
class consumable(unconsumed) Configuration : private std::unordered_map<std::string, conf_value_t>
{
+ friend std::ostream &operator<<(std::ostream &out, const Configuration &obj);
public:
- return_typestate(unconsumed)
- explicit Configuration();
+ return_typestate(unconsumed) explicit Configuration();
- return_typestate(unconsumed)
- explicit Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept;
+ return_typestate(unconsumed) explicit Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept;
- explicit Configuration(Configuration &&other param_typestate(unconsumed)) = default;
+ explicit Configuration(Configuration && other param_typestate(unconsumed)) = default;
~Configuration() = default;
- callable_when(unconsumed)
- void read(std::basic_istream<char> &input);
+ callable_when(unconsumed) void read(std::basic_istream<char> & input);
template <typename T>
callable_when(unconsumed) std::optional<T> value(const char *path) const
{
if(use_global)
return instance()->value<T>(path);
-
+
if(this->count(path) == 0) {
return std::nullopt;
}
@@ -64,7 +62,15 @@ public:
const auto value = at(path);
if constexpr(std::is_same_v<T, QString> || std::is_same_v<T, std::string>) {
- auto r = std::get<std::string>(value);
+ auto r = [&value]() {
+ if(std::holds_alternative<std::string>(value))
+ return std::get<std::string>(value);
+ else if(std::holds_alternative<int>(value))
+ return std::to_string(std::get<int>(value));
+ else
+ return std::get<bool>(value) ? std::string("true") : std::string("false");
+ }();
+
if(r.front() == '~')
r.replace(0, 1, m_homePath);
@@ -76,14 +82,14 @@ public:
} else if constexpr(std::is_same_v<T, QStringList>) {
return std::make_optional(QString::fromStdString(std::get<std::string>(value)).split(';'));
- } else if (std::holds_alternative<T>(value)) {
+ } 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
- static void move_global(std::unique_ptr<Configuration> &&conf);
+ static void move_global(std::unique_ptr<Configuration> && conf);
private:
static Configuration *instance();
@@ -93,5 +99,6 @@ private:
};
void setShortcut(QAction *action, const char *name);
+std::ostream &operator<<(std::ostream &out, const Configuration &obj);
#endif // SMOLBOTE_CONFIGURATION_H