From e70f0b4de81d24d22a29a2af03c669368fce6af2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 24 Nov 2018 20:38:48 +0100 Subject: wanda: initial commit --- src/main.cpp | 16 ++++++++++++++++ src/optional.hpp | 36 ++++++++++++++++++++++++++++++++++++ src/setting.cpp | 29 +++++++++++++++++++++++++++++ src/setting.hpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/type_wrapper.hpp | 23 +++++++++++++++++++++++ src/variant.cpp | 17 +++++++++++++++++ src/variant.hpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 216 insertions(+) create mode 100644 src/main.cpp create mode 100644 src/optional.hpp create mode 100644 src/setting.cpp create mode 100644 src/setting.hpp create mode 100644 src/type_wrapper.hpp create mode 100644 src/variant.cpp create mode 100644 src/variant.hpp (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fb2e0bf --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,16 @@ +#include "setting.hpp" +#include "optional.hpp" + +#include +#include + +int main() { + using namespace wanda::literals; + using namespace wanda::std_ext; + + with("org.gnome.desktop.background"_setting, [](auto & setting){ + with(setting.template get("picture-uri"_key), [](auto & value){ + std::cout << value << '\n'; + }) || []{ std::cerr << "No such key!\n"; }; + }) || []{ std::cerr << "No such setting!\n"; }; +} diff --git a/src/optional.hpp b/src/optional.hpp new file mode 100644 index 0000000..c178d59 --- /dev/null +++ b/src/optional.hpp @@ -0,0 +1,36 @@ +#ifndef WANDA_OPTIONAL_HPP +#define WANDA_OPTIONAL_HPP + +#include + +namespace wanda::std_ext { + +struct failable { + + constexpr static auto success() { return failable{false}; } + constexpr static auto failure() { return failable{true}; } + + template + constexpr auto operator ||(Handler handler) const { + if(m_failed) { + handler(); + } + } + +private: + constexpr explicit failable(bool failed) : m_failed{failed} { }; + bool const m_failed; +}; + +template +auto with(std::optional && object, HandlerType handler) { + if(object) { + handler(object.value()); + return failable::success(); + } + return failable::failure(); +} + +} + +#endif \ No newline at end of file diff --git a/src/setting.cpp b/src/setting.cpp new file mode 100644 index 0000000..9ddbfe8 --- /dev/null +++ b/src/setting.cpp @@ -0,0 +1,29 @@ +#include "setting.hpp" + +namespace wanda { + +namespace literals { + key operator""_key(char const * str, std::size_t len) { + return key{{str, len}}; + } + + std::optional operator""_setting(char const * str, std::size_t len) { + auto source = g_settings_schema_source_get_default(); + auto schema = g_settings_schema_source_lookup(source, str, true); + if(schema) { + g_settings_schema_unref(schema); + return setting{::wanda::schema{{str, len}}}; + } + return std::nullopt; + } +} + +setting::setting(schema schema) : m_value{g_settings_new(schema.get().c_str())} { } + +setting::setting(setting const & other) : m_value{reinterpret_cast(g_object_ref(other.m_value))} { } + +setting::~setting() { + g_clear_object(&m_value); +} + +} \ No newline at end of file diff --git a/src/setting.hpp b/src/setting.hpp new file mode 100644 index 0000000..6293dd3 --- /dev/null +++ b/src/setting.hpp @@ -0,0 +1,48 @@ +#ifndef WANDA_setting_HPP +#define WANDA_setting_HPP + +#include + +#include +#include +#include +#include + +#include "type_wrapper.hpp" +#include "variant.hpp" +#include + +namespace wanda { + +struct setting; +using schema = type_wrapper; +using key = type_wrapper; + +namespace literals { +key operator""_key(char const * str, std::size_t len); +std::optional operator""_setting(char const * str, std::size_t len); +} + +struct setting { + ~setting(); + + setting(setting const & other); + + template std::optional get(key key) const { + auto value = variant{g_settings_get_value(m_value, key.get().c_str())}; + return value.get(); + } + +private: + explicit setting(schema schema); + + GSettings * m_value; + + friend std::optional literals::operator""_setting(char const *, std::size_t); +}; + + +} + + +#endif \ No newline at end of file diff --git a/src/type_wrapper.hpp b/src/type_wrapper.hpp new file mode 100644 index 0000000..d3bf694 --- /dev/null +++ b/src/type_wrapper.hpp @@ -0,0 +1,23 @@ +#ifndef WANDA_TYPE_WRAPPER_HPP +#define WANDA_TYPE_WRAPPER_HPP + +#include + +namespace wanda { + +template +struct type_wrapper { + + explicit type_wrapper(InnerType value) : m_value{std::move(value)} { } + + constexpr explicit operator InnerType const & () const { return get(); } + + constexpr InnerType const & get() const { return m_value; } + +private: + InnerType const m_value; +}; + +} + +#endif \ No newline at end of file diff --git a/src/variant.cpp b/src/variant.cpp new file mode 100644 index 0000000..54e484e --- /dev/null +++ b/src/variant.cpp @@ -0,0 +1,17 @@ +#include "variant.hpp" + +namespace wanda { + +variant::variant(GVariant * value) : m_value{value} { } + +variant::~variant() { + if(m_value) { + g_variant_unref(m_value); + } +} + +bool variant::is_of_type(GVariantType const * const type) const { + return g_variant_is_of_type(m_value, type); +} + +} \ No newline at end of file diff --git a/src/variant.hpp b/src/variant.hpp new file mode 100644 index 0000000..8a5fb03 --- /dev/null +++ b/src/variant.hpp @@ -0,0 +1,47 @@ +#ifndef WANDA_VARIANT_HPP +#define WANDA_VARIANT_HPP + +#include + +#include +#include +#include + +namespace wanda { + +struct variant { + + explicit variant(GVariant * variant); + + ~variant(); + + template std::optional get() const { + if(!m_value) { + return std::nullopt; + } + + if constexpr(std::is_same_v) { + if(is_of_type(G_VARIANT_TYPE_BOOLEAN)) { + return static_cast(g_variant_get_boolean(m_value)); + } + } else if constexpr(std::is_same_v) { + if(is_of_type(G_VARIANT_TYPE_STRING)) { + auto length = gsize{}; + auto value = g_variant_get_string(m_value, &length); + return std::string(value, static_cast(length)); + } + } + + return std::nullopt; + } + + +private: + bool is_of_type(GVariantType const * const type) const; + + GVariant * const m_value; +}; + +} + +#endif \ No newline at end of file -- cgit v1.2.3