diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2018-11-24 20:38:48 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2018-11-24 20:38:48 +0100 |
| commit | e70f0b4de81d24d22a29a2af03c669368fce6af2 (patch) | |
| tree | f91dfd02434ce460e6120c7747aa0092cbd2327f /src | |
| download | wanda-e70f0b4de81d24d22a29a2af03c669368fce6af2.tar.xz wanda-e70f0b4de81d24d22a29a2af03c669368fce6af2.zip | |
wanda: initial commit
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 16 | ||||
| -rw-r--r-- | src/optional.hpp | 36 | ||||
| -rw-r--r-- | src/setting.cpp | 29 | ||||
| -rw-r--r-- | src/setting.hpp | 48 | ||||
| -rw-r--r-- | src/type_wrapper.hpp | 23 | ||||
| -rw-r--r-- | src/variant.cpp | 17 | ||||
| -rw-r--r-- | src/variant.hpp | 47 |
7 files changed, 216 insertions, 0 deletions
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 <iostream> +#include <string> + +int main() { + using namespace wanda::literals; + using namespace wanda::std_ext; + + with("org.gnome.desktop.background"_setting, [](auto & setting){ + with(setting.template get<std::string>("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 <optional> + +namespace wanda::std_ext { + +struct failable { + + constexpr static auto success() { return failable{false}; } + constexpr static auto failure() { return failable{true}; } + + template<typename Handler> + constexpr auto operator ||(Handler handler) const { + if(m_failed) { + handler(); + } + } + +private: + constexpr explicit failable(bool failed) : m_failed{failed} { }; + bool const m_failed; +}; + +template<typename ObjectType, typename HandlerType> +auto with(std::optional<ObjectType> && 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<setting> 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<GSettings *>(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 <gio/gio.h> + +#include <cstddef> +#include <optional> +#include <string> +#include <type_traits> + +#include "type_wrapper.hpp" +#include "variant.hpp" +#include <iostream> + +namespace wanda { + +struct setting; +using schema = type_wrapper<std::string, struct SchemaTag>; +using key = type_wrapper<std::string, struct KeyTag>; + +namespace literals { +key operator""_key(char const * str, std::size_t len); +std::optional<setting> operator""_setting(char const * str, std::size_t len); +} + +struct setting { + ~setting(); + + setting(setting const & other); + + template<typename TargetType> std::optional<TargetType> get(key key) const { + auto value = variant{g_settings_get_value(m_value, key.get().c_str())}; + return value.get<TargetType>(); + } + +private: + explicit setting(schema schema); + + GSettings * m_value; + + friend std::optional<setting> 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 <utility> + +namespace wanda { + +template<typename InnerType, typename TagType> +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 <gio/gio.h> + +#include <optional> +#include <string> +#include <type_traits> + +namespace wanda { + +struct variant { + + explicit variant(GVariant * variant); + + ~variant(); + + template<typename Type> std::optional<Type> get() const { + if(!m_value) { + return std::nullopt; + } + + if constexpr(std::is_same_v<Type, bool>) { + if(is_of_type(G_VARIANT_TYPE_BOOLEAN)) { + return static_cast<bool>(g_variant_get_boolean(m_value)); + } + } else if constexpr(std::is_same_v<Type, std::string>) { + 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<std::size_t>(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 |
