/** * @file setting.hpp * @author Felix Morgner (felix.morgner@gmail.com) * @since 1.0.0 */ #ifndef WANDA_setting_HPP #define WANDA_setting_HPP #include "deferred_failure.hpp" #include "type_wrapper.hpp" #include #include #include #include #include #include #include #include #include namespace wanda { struct setting; /** * @brief A convenience type to represent setting keys */ using key = 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>; value_type operator*() const; 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()); } else { static_assert(deferred_failure{}, "Invalid argument type!"); } }()} { } ~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 #endif