From 577fc0845718ed8ad5bebf02a277c0579a817f77 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 17 May 2024 17:58:38 +0200 Subject: wanda: restructure source layout --- source/lib/include/wanda/system/setting.hpp | 156 ++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 source/lib/include/wanda/system/setting.hpp (limited to 'source/lib/include/wanda/system/setting.hpp') diff --git a/source/lib/include/wanda/system/setting.hpp b/source/lib/include/wanda/system/setting.hpp new file mode 100644 index 0000000..e0be3f4 --- /dev/null +++ b/source/lib/include/wanda/system/setting.hpp @@ -0,0 +1,156 @@ +/** + * @file setting.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_SETTING_HPP +#define WANDA_SYSTEM_SETTING_HPP + +#include "wanda/meta/deferred_failure.hpp" +#include "wanda/meta/type_wrapper.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace wanda::system +{ + struct setting; + + /** + * @brief A convenience type to represent setting keys + */ + using key = meta::type_wrapper; + + namespace literals + { + /** + * @brief UDL to create setting keys + */ + key operator""_key(char const * str, std::size_t len); + + /** + * @brief UDL to create setting schemas + */ + std::optional operator""_setting(char const * str, std::size_t lent); + } // namespace literals + + /** + * @brief A simple wrapper for GSettings Schemas + */ + struct setting + { + struct entry + { + using value_type = std::variant>; + + /** + * @brief Get the value of the settings entry + */ + value_type operator*() const; + + /** + * @brief Assign the given @p value to the settings entry + * + * @returns @p true iff. the value could be successfully assigned + */ + template + bool operator=(Type value) + { + struct setting_applier + { + setting_applier(GSettings * setting, gchar const * key, Type value) noexcept + : m_result{[&] { + if constexpr (std::is_same_v) + { + return g_settings_set_boolean(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_int(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_int64(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_uint(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_uint64(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_double(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_string(setting, key, value.c_str()); + } + else if constexpr (std::is_same_v>) + { + auto temp = std::vector{value.size() + 1}; + std::transform(value.begin(), value.end(), temp.begin(), [](auto const & str) { return str.c_str(); }); + return g_settings_set_strv(setting, key, temp.data()); + } + }()} + { + } + + ~setting_applier() + { + g_settings_sync(); + } + + operator bool() const + { + return m_result; + } + + private: + gboolean const m_result; + }; + + return setting_applier{m_settings.get(), m_key.get().c_str(), value}; + } + + private: + entry(setting const & schema, key key); + + std::unique_ptr m_settings; + + key m_key; + + friend setting; + }; + + /** + * @brief Get the entry for the given key + * + * @return An std::optional wrapping the entry associated with + * the given key, or an empty std::optional if the desired key + * does not exist in the setting's schema. + */ + std::optional operator[](key key) const; + + private: + explicit setting(GSettingsSchema * schema); + + std::unique_ptr m_schema; + + friend std::optional literals::operator""_setting(char const *, std::size_t); + }; + +} // namespace wanda::system + +#endif \ No newline at end of file -- cgit v1.2.3