aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2018-11-24 20:38:48 +0100
committerFelix Morgner <felix.morgner@gmail.com>2018-11-24 20:38:48 +0100
commite70f0b4de81d24d22a29a2af03c669368fce6af2 (patch)
treef91dfd02434ce460e6120c7747aa0092cbd2327f /src
downloadwanda-e70f0b4de81d24d22a29a2af03c669368fce6af2.tar.xz
wanda-e70f0b4de81d24d22a29a2af03c669368fce6af2.zip
wanda: initial commit
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp16
-rw-r--r--src/optional.hpp36
-rw-r--r--src/setting.cpp29
-rw-r--r--src/setting.hpp48
-rw-r--r--src/type_wrapper.hpp23
-rw-r--r--src/variant.cpp17
-rw-r--r--src/variant.hpp47
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