/* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original * location: https://neueland.iserlohn-fortress.net/smolbote.hg * * SPDX-License-Identifier: GPL-3.0 */ #ifndef CONFIGURATION_H #define CONFIGURATION_H #include #include #include #include #include class Configuration { public: explicit Configuration(const std::string &path, const std::string &home); ~Configuration(); bool read(const QString &path); bool writeIfNeeded(const std::string &path = std::string()); std::vector childrenSettings(const char *name = ""); std::vector childrenGroups(const char *name = ""); template std::optional value(const char *path) const { // if setting doesn't exist, give back a nullopt if(!m_userCfg->exists(path)) { return std::nullopt; } const libconfig::Setting &v = m_userCfg->lookup(path); if constexpr(std::is_same_v) { std::string r = castToString(v); // check if it's a path if(r.front() == '~') { r.replace(0, 1, m_homePath); } return std::optional(r); } else return std::optional(static_cast(v)); } template bool setValue(std::string path, const T &val) { if(!m_userCfg->exists(path)) { return false; } libconfig::Setting &setting = m_userCfg->lookup(path); // compiler complained about operator= not taking unsinged ints, longs and long longs if constexpr(std::is_unsigned_v && !std::is_same_v) { setting = static_cast>(val); } else if constexpr(std::is_same_v) { switch(setting.getType()) { case libconfig::Setting::TypeNone: break; case libconfig::Setting::TypeInt: case libconfig::Setting::TypeInt64: setting = std::stoi(static_cast(val)); break; case libconfig::Setting::TypeFloat: setting = std::stod(static_cast(val)); break; case libconfig::Setting::TypeString: setting = static_cast(val).c_str(); break; case libconfig::Setting::TypeBoolean: if(static_cast(val) == "true") { setting = true; } else if(static_cast(val) == "false") { setting = false; } break; case libconfig::Setting::TypeGroup: break; case libconfig::Setting::TypeArray: break; case libconfig::Setting::TypeList: break; } } else { setting = val; } changed = true; return true; } private: std::string castToString(const libconfig::Setting &v) const; bool changed = false; std::string m_homePath; std::string m_userCfgPath; libconfig::Config *m_userCfg; }; // replace ~ with home std::string patchHome(const std::string &path, const std::string &home); #endif // CONFIGURATION_H