summaryrefslogtreecommitdiff
path: root/discord
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2020-11-01 01:18:54 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2020-11-01 01:18:54 -0500
commit18f4f7ce5e597f83c67349a91f67cfa5a317069d (patch)
tree27cff723e810581afad439acd672d287925c8004 /discord
parent925d7afaf87bf79ca2d978a94e9f5144ea57c170 (diff)
downloadabaddon-portaudio-18f4f7ce5e597f83c67349a91f67cfa5a317069d.tar.gz
abaddon-portaudio-18f4f7ce5e597f83c67349a91f67cfa5a317069d.zip
gross json preprocessor abuse time
Diffstat (limited to 'discord')
-rw-r--r--discord/json.hpp153
1 files changed, 124 insertions, 29 deletions
diff --git a/discord/json.hpp b/discord/json.hpp
index 3f78391..40f078f 100644
--- a/discord/json.hpp
+++ b/discord/json.hpp
@@ -1,45 +1,140 @@
#pragma once
#include <nlohmann/json.hpp>
+#include <optional>
-#define JS_D(k, t) \
- do { \
- j.at(k).get_to(t); \
+namespace detail { // more or less because idk what to name this stuff
+template<typename T>
+struct is_optional : ::std::false_type {};
+
+template<typename T>
+struct is_optional<::std::optional<T>> : ::std::true_type {};
+
+template<typename T>
+inline void json_direct(const ::nlohmann::json &j, const char *key, T &val) {
+ if constexpr (is_optional<T>::value)
+ val = j.at(key).get<T::value_type>();
+ else
+ j.at(key).get_to(val);
+}
+
+template<typename T>
+inline void json_optional(const ::nlohmann::json &j, const char *key, T &val) {
+ if constexpr (is_optional<T>::value) {
+ if (j.contains(key))
+ val = j.at(key).get<T::value_type>();
+ else
+ val = ::std::nullopt;
+ } else {
+ if (j.contains(key))
+ j.at(key).get_to(val);
+ }
+}
+
+template<typename T>
+inline void json_nullable(const ::nlohmann::json &j, const char *key, T &val) {
+ if constexpr (is_optional<T>::value) {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ val = at.get<T::value_type>();
+ else
+ val = std::nullopt;
+ } else {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ at.get_to(val);
+ }
+}
+
+template<typename T>
+inline void json_optional_nullable(const ::nlohmann::json &j, const char *key, T &val) {
+ if constexpr (is_optional<T>::value) {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ val = at.get<T::value_type>();
+ else
+ val = std::nullopt;
+ } else {
+ val = std::nullopt;
+ }
+ } else {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ at.get_to(val);
+ }
+ }
+}
+
+template<typename T>
+inline void json_update_optional_nullable(const ::nlohmann::json &j, const char *key, T &val) {
+ if constexpr (is_optional<T>::value) {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ val = at.get<T::value_type>();
+ else
+ val = std::nullopt;
+ }
+ } else {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (!at.is_null())
+ at.get_to(val);
+ else
+ val = T();
+ }
+ }
+}
+
+template<typename T, typename U>
+inline void json_update_optional_nullable_default(const ::nlohmann::json &j, const char *key, T &val, const U &fallback) {
+ if constexpr (is_optional<T>::value) {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (at.is_null())
+ val = fallback;
+ else
+ val = at.get<T::value_type>();
+ }
+ } else {
+ if (j.contains(key)) {
+ const auto &at = j.at(key);
+ if (at.is_null())
+ val = fallback;
+ else
+ at.get_to(val);
+ }
+ }
+}
+} // namespace detail
+
+#define JS_D(k, t) \
+ do { \
+ detail::json_direct(j, k, t); \
} while (0)
-#define JS_O(k, t) \
- do { \
- if (j.contains(k)) j.at(k).get_to(t); \
+#define JS_O(k, t) \
+ do { \
+ detail::json_optional(j, k, t); \
} while (0)
-#define JS_N(k, t) \
- do { \
- if (!j.at(k).is_null()) j.at(k).get_to(t); \
+#define JS_N(k, t) \
+ do { \
+ detail::json_nullable(j, k, t); \
} while (0)
#define JS_ON(k, t) \
do { \
- if (j.contains(k) && !j.at(k).is_null()) \
- j.at(k).get_to(t); \
+ detail::json_optional_nullable(j, k, t); \
} while (0)
-#define JS_RD(k, t) \
- do { \
- if (j.contains(k)) { \
- if (j.at(k).is_null()) { \
- t = decltype(t)(); \
- } else { \
- j.at(k).get_to(t); \
- } \
- } \
+#define JS_RD(k, t) \
+ do { \
+ detail::json_update_optional_nullable(j, k, t); \
} while (0)
-#define JS_RV(k, t, d) \
- do { \
- if (j.contains(k)) { \
- if (j.at(k).is_null()) { \
- t = d; \
- } else { \
- j.at(k).get_to(t); \
- } \
- } \
+#define JS_RV(k, t, d) \
+ do { \
+ detail::json_update_optional_nullable_default(j, k, t, d); \
} while (0)