Dawn/src/dawn/util/JSON.cpp

130 lines
3.4 KiB
C++

// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "JSON.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
glm::vec3 JSON::vec3(const json &j) {
if(j.type() == json::value_t::array) {
assertTrue(j.size() == 3, "Invalid size for vec3");
return glm::vec3(j[0].get<float_t>(), j[1].get<float_t>(), j[2].get<float_t>());
} else if(j.type() == json::value_t::object) {
assertTrue(j.contains("x"), "Missing x in vec3");
assertTrue(j.contains("y"), "Missing y in vec3");
assertTrue(j.contains("z"), "Missing z in vec3");
return glm::vec3(
j["x"].get<float_t>(),
j["y"].get<float_t>(),
j["z"].get<float_t>()
);
}
assertUnreachable("Invalid JSON type for vec3");
return glm::vec3(0.0f);
}
glm::vec4 JSON::vec4(const json &j) {
if(j.type() == json::value_t::array) {
assertTrue(j.size() == 4, "Invalid size for vec4");
return glm::vec4(
j[0].get<float_t>(),
j[1].get<float_t>(),
j[2].get<float_t>(),
j[3].get<float_t>()
);
} else if(j.type() == json::value_t::object) {
assertTrue(j.contains("x"), "Missing x in vec4");
assertTrue(j.contains("y"), "Missing y in vec4");
assertTrue(j.contains("z"), "Missing z in vec4");
assertTrue(j.contains("w"), "Missing w in vec4");
return glm::vec4(
j["x"].get<float_t>(),
j["y"].get<float_t>(),
j["z"].get<float_t>(),
j["w"].get<float_t>()
);
}
assertUnreachable("Invalid JSON type for vec4");
return glm::vec4(0.0f);
}
struct Color JSON::color(const json &j) {
if(j.type() == json::value_t::array) {
return {
j[0].get<float_t>(),
j[1].get<float_t>(),
j[2].get<float_t>(),
j[3].get<float_t>()
};
} else if(j.type() == json::value_t::object) {
float_t r, g, b, a = 1.0f;
if(j.contains("r")) {
r = j["r"].get<float_t>();
} else if(j.contains("red")) {
r = j["red"].get<float_t>();
} else {
assertTrue(j.contains("red"), "Missing red in color");
}
if(j.contains("g")) {
g = j["g"].get<float_t>();
} else if(j.contains("green")) {
g = j["green"].get<float_t>();
} else {
assertTrue(j.contains("green"), "Missing green in color");
}
if(j.contains("b")) {
b = j["b"].get<float_t>();
} else if(j.contains("blue")) {
b = j["blue"].get<float_t>();
} else {
assertTrue(j.contains("blue"), "Missing blue in color");
}
if(j.contains("a")) {
a = j["a"].get<float_t>();
} else if(j.contains("alpha")) {
a = j["alpha"].get<float_t>();
}
return { r, g, b, a };
} else if(j.type() == json::value_t::string) {
return Color::fromString(j.get<std::string>());
}
assertUnreachable("Invalid JSON type for color");
return COLOR_WHITE;
}
void JSON::mergeObjectsRecursive(json &a, const json &b) {
assertTrue(a.type() == json::value_t::object, "a is not an object");
assertTrue(b.type() == json::value_t::object, "b is not an object");
for(auto &item : b.items()) {
auto &key = item.key();
auto &value = item.value();
if(a.contains(key)) {
if(
a[key].type() == json::value_t::object &&
value.type() == json::value_t::object
) {
mergeObjectsRecursive(a[key], value);
} else {
a[key] = json(value);
}
} else {
a[key] = json(value);
}
}
}