summaryrefslogtreecommitdiffhomepage
path: root/serialize/magnum-vector2i.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'serialize/magnum-vector2i.hpp')
-rw-r--r--serialize/magnum-vector2i.hpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/serialize/magnum-vector2i.hpp b/serialize/magnum-vector2i.hpp
new file mode 100644
index 00000000..eb445e21
--- /dev/null
+++ b/serialize/magnum-vector2i.hpp
@@ -0,0 +1,42 @@
+#include <cstdio>
+#include <string>
+#include <limits>
+#include <exception>
+#include <Magnum/Magnum.h>
+#include <Magnum/Math/Vector2.h>
+#include <nlohmann/json.hpp>
+
+namespace nlohmann {
+
+template<typename t>
+requires std::is_integral_v<t>
+struct adl_serializer<Magnum::Math::Vector2<t>> final {
+ static void to_json(json& j, const Magnum::Math::Vector2<t>& val)
+ {
+ char buf[64];
+ using type = std::conditional_t<std::is_signed_v<t>, std::intmax_t, std::uintmax_t>;
+ constexpr auto format_string = std::is_signed_v<t> ? "%jd x %jd" : "%ju x %ju";
+ snprintf(buf, sizeof(buf), format_string, (type)val[0], (type)val[1]);
+ j = buf;
+ }
+ static void from_json(const json& j, Magnum::Math::Vector2<t>& val)
+ {
+ std::string str = j;
+ using type = std::conditional_t<std::is_signed_v<t>, std::intmax_t, std::uintmax_t>;
+ constexpr auto format_string = std::is_signed_v<t> ? "%jd x %jd%n" : "%ju x %ju%n";
+ type x = 0, y = 0;
+ int n = 0;
+ int ret = std::sscanf(str.c_str(), format_string, &x, &y, &n);
+ if (ret != 2 || (std::size_t)n != str.size() || x != (type)x || y != (type)y)
+ {
+ std::string msg; msg.reserve(128);
+ msg += "failed to parse string '";
+ msg += str;
+ msg += "' as Magnum::Vector2i";
+ throw std::invalid_argument(msg);
+ }
+ val = { (t)x, (t)y };
+ }
+};
+
+} // namespace nlohmann