diff options
Diffstat (limited to 'serialize/magnum-vector2i.hpp')
-rw-r--r-- | serialize/magnum-vector2i.hpp | 42 |
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 |