matjson 3/3, compiles but mod about.md dont load for some reason

This commit is contained in:
matcool 2024-11-09 15:16:24 -03:00
parent d1d34aab8f
commit 9ed55c4e7b
33 changed files with 142 additions and 141 deletions

View file

@ -236,8 +236,8 @@ if (ANDROID)
endif()
set(MAT_JSON_AS_INTERFACE ON)
CPMAddPackage("gh:geode-sdk/json#1b182dd")
CPMAddPackage("gh:geode-sdk/result@1.1.0")
CPMAddPackage("gh:geode-sdk/json#8c6c325")
CPMAddPackage("gh:fmtlib/fmt#10.2.1")
target_compile_definitions(${PROJECT_NAME} INTERFACE MAT_JSON_DYNAMIC=1)

View file

@ -41,7 +41,7 @@
#include <Geode/utils/casts.hpp>
#ifndef GEODE_IS_MEMBER_TEST
#include <matjson3.hpp>
#include <matjson.hpp>
#endif
namespace geode {

View file

@ -2,7 +2,7 @@
#include "../DefaultInclude.hpp"
#include "../utils/general.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include "Tulip.hpp"
#include <cinttypes>
#include <string_view>

View file

@ -3,7 +3,7 @@
#include "Event.hpp"
#include "Loader.hpp"
#include "Mod.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
namespace geode::ipc {
#ifdef GEODE_IS_WINDOWS

View file

@ -8,7 +8,7 @@
#include "Types.hpp"
#include <atomic>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <mutex>
#include <optional>
#include <string_view>

View file

@ -7,7 +7,7 @@
#include <ccTypes.h>
#include <chrono>
#include <filesystem>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <type_traits>
#include <fmt/core.h>
// for formatting std::vector and such

View file

@ -13,7 +13,7 @@
#include "Types.hpp"
#include "Loader.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <matjson/stl_serialize.hpp>
#include <optional>
#include <string_view>

View file

@ -4,7 +4,7 @@
#include "../utils/VersionInfo.hpp"
#include "Types.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <memory>
namespace geode {

View file

@ -2,7 +2,7 @@
#include "../DefaultInclude.hpp"
#include "../platform/cplatform.h"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <string>

View file

@ -1,6 +1,6 @@
#pragma once
#include <matjson3.hpp>
#include <matjson.hpp>
#include "../loader/Log.hpp"
#include <set>
#include <variant>
@ -223,6 +223,13 @@ namespace geode {
* @returns The key, which is a no-op value if it didn't exist
*/
JsonExpectedValue has(std::string_view key);
/**
* Check if this object has an optional key. Asserts that this JSON
* value is an object. If the key doesn't exist, or the value is null, returns a
* `JsonExpectValue` that does nothing
* @returns The key, which is a no-op value if it didn't exist, or was null
*/
JsonExpectedValue hasNullable(std::string_view key);
/**
* Check if this object has an optional key. Asserts that this JSON
* value is an object. If the key doesn't exist, sets an error and

View file

@ -2,7 +2,7 @@
#include "../DefaultInclude.hpp"
#include <string_view>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <tuple>
#include <Geode/Result.hpp>
@ -258,9 +258,9 @@ requires std::is_same_v<V, geode::VersionInfo> || std::is_same_v<V, geode::Compa
struct matjson::Serialize<V> {
static geode::Result<V, std::string> fromJson(Value const& value)
{
auto str = GEODE_UNWRAP(value.asString());
auto version = GEODE_UNWRAP(V::parse(str).mapErr([](auto&& err) {
return geode::Err("Invalid version format: {}", err);
GEODE_UNWRAP_INTO(auto str, value.asString());
GEODE_UNWRAP_INTO(auto version, V::parse(str).mapErr([](auto&& err) {
return fmt::format("Invalid version format: {}", err);
}));
return geode::Ok(version);
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <matjson3.hpp>
#include <matjson.hpp>
#include "casts.hpp"
#include "general.hpp"
#include "../DefaultInclude.hpp"

View file

@ -5,7 +5,7 @@
#include "../loader/Event.hpp"
#include "Task.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <Geode/DefaultInclude.hpp>
#include <filesystem>
#include <string>
@ -15,7 +15,7 @@ template <>
struct matjson::Serialize<std::filesystem::path> {
static geode::Result<std::filesystem::path, std::string> fromJson(Value const& value)
{
auto str = GEODE_UNWRAP(value.asString());
GEODE_UNWRAP_INTO(auto str, value.asString());
return geode::Ok(std::filesystem::path(str).make_preferred());
}

View file

@ -9,7 +9,7 @@
#include <string>
#include <vector>
#include <filesystem>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <charconv>
#include <clocale>
#include <type_traits>
@ -170,9 +170,8 @@ namespace geode {
template<>
struct matjson::Serialize<geode::ByteVector> {
static Value toJson(geode::ByteVector const& bytes)
{
return matjson::Array(bytes.begin(), bytes.end());
static Value toJson(geode::ByteVector const& bytes) {
return std::vector<matjson::Value>(bytes.begin(), bytes.end());
}
};

View file

@ -1,7 +1,7 @@
#pragma once
#include <Geode/loader/Loader.hpp> // another great circular dependency fix
#include <matjson3.hpp>
#include <matjson.hpp>
#include <Geode/Result.hpp>
#include "Task.hpp"
#include <chrono>

View file

@ -98,7 +98,7 @@ std::string_view Hook::Impl::getDisplayName() const {
}
matjson::Value Hook::Impl::getRuntimeInfo() const {
auto json = matjson::Object();
matjson::Value json;
json["address"] = std::to_string(reinterpret_cast<uintptr_t>(m_address));
json["detour"] = std::to_string(reinterpret_cast<uintptr_t>(m_detour));
json["name"] = m_displayName;

View file

@ -1,6 +1,6 @@
#include <Geode/loader/IPC.hpp>
#include "IPC.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <Geode/loader/Mod.hpp>
using namespace geode::prelude;
@ -34,7 +34,7 @@ matjson::Value ipc::processRaw(void* rawHandle, std::string const& buffer) {
matjson::Value reply;
auto res = matjson::Value::parse(buffer);
if (error.size() > 0) {
if (!res) {
log::warn("Received IPC message that isn't valid JSON: {}", res.unwrapErr());
return reply;
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <string>
#include <matjson3.hpp>
#include <matjson.hpp>
namespace geode::ipc {
void setup();

View file

@ -2,7 +2,7 @@
#include "FileWatcher.hpp"
#include <matjson3.hpp>
#include <matjson.hpp>
#include <Geode/loader/Dirs.hpp>
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>

View file

@ -190,15 +190,12 @@ Result<> Mod::Impl::loadData() {
auto savedPath = m_saveDirPath / "saved.json";
if (std::filesystem::exists(savedPath)) {
GEODE_UNWRAP_INTO(auto data, utils::file::readString(savedPath));
std::string error;
auto res = matjson::parse(data, error);
if (error.size() > 0) {
return Err("Unable to parse saved values: " + error);
}
m_saved = res.value();
if (!m_saved.is_object()) {
m_saved = GEODE_UNWRAP(matjson::parse(data).mapErr([](auto&& err) {
return fmt::format("Unable to parse saved values: {}", err);
}));
if (!m_saved.isObject()) {
log::warn("saved.json was somehow not an object, forcing it to one");
m_saved = matjson::Object();
m_saved = matjson::Value::object();
}
}
@ -218,11 +215,15 @@ Result<> Mod::Impl::saveData() {
// saveData is expected to be synchronous, and always called from GD thread
ModStateEvent(m_self, ModEventType::DataSaved).post();
auto res = utils::file::writeString(m_saveDirPath / "settings.json", json.dump());
auto res = json.dump().andThen([&](auto const& str) {
return utils::file::writeString(m_saveDirPath / "settings.json", str);
});
if (!res) {
log::error("Unable to save settings: {}", res.unwrapErr());
}
auto res2 = utils::file::writeString(m_saveDirPath / "saved.json", m_saved.dump());
auto res2 = m_saved.dump().andThen([&](auto const& str) {
return utils::file::writeString(m_saveDirPath / "saved.json", str);
});
if (!res2) {
log::error("Unable to save values: {}", res2.unwrapErr());
}
@ -387,7 +388,7 @@ Result<> Mod::Impl::uninstall(bool deleteSaveData) {
ModRequestedAction::Uninstall;
// Make loader forget the mod should be disabled
Mod::get()->getSaveContainer().try_erase("should-load-" + m_metadata.getID());
Mod::get()->getSaveContainer().erase("should-load-" + m_metadata.getID());
std::error_code ec;
std::filesystem::remove(m_metadata.getPath(), ec);
@ -674,14 +675,14 @@ std::string_view Mod::Impl::expandSpriteName(std::string_view name) {
ModJson Mod::Impl::getRuntimeInfo() const {
auto json = m_metadata.toJSON();
auto obj = matjson::Object();
obj["hooks"] = matjson::Array();
auto obj = matjson::Value::object();
obj["hooks"] = matjson::Value::array();
for (auto hook : m_hooks) {
obj["hooks"].as_array().push_back(ModJson(hook->getRuntimeInfo()));
obj["hooks"].push(ModJson(hook->getRuntimeInfo()));
}
obj["patches"] = matjson::Array();
obj["patches"] = matjson::Value::array();
for (auto patch : m_patches) {
obj["patches"].as_array().push_back(ModJson(patch->getRuntimeInfo()));
obj["patches"].push(ModJson(patch->getRuntimeInfo()));
}
obj["loaded"] = m_enabled;
obj["temp-dir"] = this->getTempDir();
@ -722,12 +723,9 @@ std::vector<LoadProblem> Mod::Impl::getProblems() const {
}
static Result<ModMetadata> getModImplInfo() {
std::string error;
auto res = matjson::parse(about::getLoaderModJson(), error);
if (error.size() > 0) {
return Err("Unable to parse mod.json: " + error);
}
matjson::Value json = res.value();
auto json = GEODE_UNWRAP(matjson::parse(about::getLoaderModJson()).mapErr([](auto&& err) {
return fmt::format("Unable to parse mod.json: {}", err);
}));
GEODE_UNWRAP_INTO(auto info, ModMetadata::create(json));
return Ok(info);

View file

@ -1,6 +1,6 @@
#pragma once
#include <matjson3.hpp>
#include <matjson.hpp>
#include "ModPatch.hpp"
#include <Geode/loader/Loader.hpp>
#include <string_view>

View file

@ -5,7 +5,7 @@
#include <Geode/utils/string.hpp>
#include <Geode/utils/general.hpp>
#include <about.hpp>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <utility>
#include <clocale>
@ -113,14 +113,14 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
auto checkerRoot = fmt::format(
"[{}/v0.0.0/mod.json]",
rawJson.contains("id") ? rawJson["id"].as_string() : "unknown.mod"
rawJson.contains("id") ? GEODE_UNWRAP(rawJson["id"].asString()) : "unknown.mod"
);
// JsonChecker did it this way too
try {
checkerRoot = fmt::format(
"[{}/{}/mod.json]",
rawJson.contains("id") ? rawJson["id"].as_string() : "unknown.mod",
rawJson.contains("version") ? rawJson["version"].as<VersionInfo>().toVString() : "v0.0.0"
rawJson.contains("id") ? GEODE_UNWRAP(rawJson["id"].asString()) : "unknown.mod",
rawJson.contains("version") ? GEODE_UNWRAP(rawJson["version"].as<VersionInfo>()).toVString() : "v0.0.0"
);
}
catch (...) { }
@ -304,10 +304,10 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
Result<ModMetadata> ModMetadata::Impl::create(ModJson const& json) {
// Check mod.json target version
auto schema = about::getLoaderVersion();
if (json.contains("geode") && json["geode"].is_string()) {
if (json.contains("geode") && json["geode"].isString()) {
GEODE_UNWRAP_INTO(
schema,
VersionInfo::parse(json["geode"].as_string()).mapErr(
VersionInfo::parse(GEODE_UNWRAP(json["geode"].asString())).mapErr(
[](auto const& err) {
return fmt::format("[mod.json] has invalid target loader version: {}", err);
}
@ -355,13 +355,9 @@ Result<ModMetadata> ModMetadata::Impl::create(ModJson const& json) {
Result<ModMetadata> ModMetadata::Impl::createFromFile(std::filesystem::path const& path) {
GEODE_UNWRAP_INTO(auto read, utils::file::readString(path));
std::string error;
auto res = matjson::parse(read, error);
if (error.size() > 0) {
return Err(std::string("Unable to parse mod.json: ") + error);
}
GEODE_UNWRAP_INTO(auto info, ModMetadata::create(res.value()));
GEODE_UNWRAP_INTO(auto info, ModMetadata::create(GEODE_UNWRAP(matjson::parse(read).mapErr([&](auto const& err) {
return fmt::format("Unable to parse mod.json: {}", err);
}))));
auto impl = info.m_impl.get();
@ -390,18 +386,13 @@ Result<ModMetadata> ModMetadata::Impl::createFromGeodeZip(file::Unzip& unzip) {
})
);
std::string error;
auto res = matjson::parse(std::string(jsonData.begin(), jsonData.end()), error);
if (error.size() > 0) {
return Err(std::string("Unable to parse mod.json: ") + error);
}
ModJson json = res.value();
ModJson json = GEODE_UNWRAP(matjson::parse(std::string(jsonData.begin(), jsonData.end())).mapErr([](auto const& err) {
return fmt::format("Unable to parse mod.json: {}", err);
}));
auto res2 = ModMetadata::create(json);
if (!res2) {
return Err("\"" + unzip.getPath().string() + "\" - " + res2.unwrapErr());
}
auto info = res2.unwrap();
auto info = GEODE_UNWRAP(ModMetadata::create(json).mapErr([&](auto const& err) {
return fmt::format("\"{}\" - {}", unzip.getPath().string(), err);
}));
auto impl = info.m_impl.get();
impl->m_path = unzip.getPath();

View file

@ -124,16 +124,11 @@ public:
// Store the value in an intermediary so if `save` fails the existing
// value loaded from disk isn't overwritten
matjson::Value value;
try {
if (sett.v3->save(value)) {
this->savedata[key] = value;
}
else {
log::error("Unable to save setting '{}' for mod {}", key, this->modID);
}
if (sett.v3->save(value)) {
this->savedata[key] = value;
}
catch(matjson::JsonException const& e) {
log::error("Unable to save setting '{}' for mod {} (JSON exception): {}", key, this->modID, e.what());
else {
log::error("Unable to save setting '{}' for mod {}", key, this->modID);
}
}
}
@ -209,11 +204,11 @@ Result<> ModSettingsManager::registerCustomSettingType(std::string_view type, Se
}
Result<> ModSettingsManager::load(matjson::Value const& json) {
if (json.is_object()) {
if (json.isObject()) {
// Save this so when custom settings are registered they can load their
// values properly
m_impl->savedata = json.as_object();
for (auto const& [key, _] : json.as_object()) {
m_impl->savedata = json;
for (auto const& [key, _] : json) {
m_impl->loadSettingValueFromSave(key);
}
}

View file

@ -104,7 +104,7 @@ uintptr_t Patch::Impl::getAddress() const {
}
matjson::Value Patch::Impl::getRuntimeInfo() const {
auto json = matjson::Object();
auto json = matjson::Value::object();
json["address"] = std::to_string(reinterpret_cast<uintptr_t>(m_address));
json["original"] = m_original;
json["patch"] = m_patch;

View file

@ -1,7 +1,7 @@
#pragma once
#include <string>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <Geode/loader/Event.hpp>
namespace geode::updater {

View file

@ -21,7 +21,11 @@ void ipcPipeThread(HANDLE pipe) {
if (ReadFile(pipe, buffer, sizeof(buffer) - 1, &read, nullptr)) {
buffer[read] = '\0';
std::string reply = ipc::processRaw((void*)pipe, buffer).dump();
auto res = ipc::processRaw((void*)pipe, buffer).dump();
if (!res) {
log::warn("Failed to process IPC message: {}", res.unwrapErr());
}
std::string reply = res.unwrapOr("");
DWORD written;
WriteFile(pipe, reply.c_str(), reply.size(), &written, nullptr);

View file

@ -172,24 +172,23 @@ static Result<matjson::Value, ServerError> parseServerPayload(web::WebResponse c
return Err(ServerError(response.code(), "Response was not valid JSON: {}", asJson.unwrapErr()));
}
auto json = std::move(asJson).unwrap();
if (!json.is_object()) {
if (!json.isObject()) {
return Err(ServerError(response.code(), "Expected object, got {}", jsonTypeToString(json.type())));
}
auto obj = json.as_object();
if (!obj.contains("payload")) {
return Err(ServerError(response.code(), "Object does not contain \"payload\" key - got {}", json.dump()));
if (!json.contains("payload")) {
return Err(ServerError(response.code(), "Object does not contain \"payload\" key - got {}", json.dump().unwrapOr("?")));
}
return Ok(obj["payload"]);
return Ok(json["payload"]);
}
static ServerError parseServerError(web::WebResponse const& error) {
// The server should return errors as `{ "error": "...", "payload": "" }`
if (auto asJson = error.json()) {
auto json = asJson.unwrap();
if (json.is_object() && json.contains("error")) {
if (json.isObject() && json.contains("error") && json["error"].isString()) {
return ServerError(
error.code(),
"{}", json.get<std::string>("error")
"{}", json["error"].asString().unwrapOr("Unknown (no error message)")
);
}
else {
@ -267,8 +266,8 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
// Verify target GD version
auto gd_obj = root.needs("gd");
std::string gd = "0.000";
if (gd_obj.has(GEODE_PLATFORM_SHORT_IDENTIFIER)) {
gd = gd_obj.has(GEODE_PLATFORM_SHORT_IDENTIFIER). get<std::string>();
if (gd_obj.hasNullable(GEODE_PLATFORM_SHORT_IDENTIFIER)) {
gd = gd_obj.hasNullable(GEODE_PLATFORM_SHORT_IDENTIFIER). get<std::string>();
}
if (gd != "*") {
@ -288,11 +287,11 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
res.metadata.setIsAPI(root.needs("api").get<bool>());
std::vector<ModMetadata::Dependency> dependencies {};
for (auto& obj : root.has("dependencies").items()) {
for (auto& obj : root.hasNullable("dependencies").items()) {
// todo: this should probably be generalized to use the same function as mod.json
bool onThisPlatform = !obj.has("platforms");
for (auto& plat : obj.has("platforms").items()) {
bool onThisPlatform = !obj.hasNullable("platforms");
for (auto& plat : obj.hasNullable("platforms").items()) {
if (PlatformID::coveredBy(plat.get<std::string>(), GEODE_PLATFORM_TARGET)) {
onThisPlatform = true;
}
@ -304,7 +303,7 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
ModMetadata::Dependency dependency;
obj.needs("mod_id").mustBe<std::string>("a valid id", &ModMetadata::validateID).into(dependency.id);
obj.needs("version").into(dependency.version);
obj.has("importance").into(dependency.importance);
obj.hasNullable("importance").into(dependency.importance);
// Check if this dependency is installed, and if so assign the `mod` member to mark that
auto mod = Loader::get()->getInstalledMod(dependency.id);
@ -317,9 +316,9 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
res.metadata.setDependencies(dependencies);
std::vector<ModMetadata::Incompatibility> incompatibilities {};
for (auto& obj : root.has("incompatibilities").items()) {
for (auto& obj : root.hasNullable("incompatibilities").items()) {
ModMetadata::Incompatibility incompatibility;
obj.has("importance").into(incompatibility.importance);
obj.hasNullable("importance").into(incompatibility.importance);
auto modIdValue = obj.needs("mod_id");
@ -362,8 +361,8 @@ Result<ServerModUpdate> ServerModUpdate::parse(matjson::Value const& raw) {
root.needs("id").into(res.id);
root.needs("version").into(res.version);
if (root.has("replacement")) {
GEODE_UNWRAP_INTO(res.replacement, ServerModReplacement::parse(root.has("replacement").json()));
if (root.hasNullable("replacement")) {
GEODE_UNWRAP_INTO(res.replacement, ServerModReplacement::parse(root.hasNullable("replacement").json()));
}
return root.ok(res);
@ -400,9 +399,9 @@ Result<ServerModMetadata> ServerModMetadata::parse(matjson::Value const& raw) {
root.needs("id").into(res.id);
root.needs("featured").into(res.featured);
root.needs("download_count").into(res.downloadCount);
root.has("about").into(res.about);
root.has("changelog").into(res.changelog);
root.has("repository").into(res.repository);
root.hasNullable("about").into(res.about);
root.hasNullable("changelog").into(res.changelog);
root.hasNullable("repository").into(res.repository);
if (root.has("created_at")) {
GEODE_UNWRAP_INTO(res.createdAt, ServerDateTime::parse(root.has("created_at").get<std::string>()));
}
@ -439,7 +438,7 @@ Result<ServerModMetadata> ServerModMetadata::parse(matjson::Value const& raw) {
return Err("Mod '{}' has no (valid) versions", res.id);
}
for (auto& item : root.has("tags").items()) {
for (auto& item : root.hasNullable("tags").items()) {
res.tags.insert(item.get<std::string>());
}
@ -705,16 +704,16 @@ ServerRequest<std::unordered_set<std::string>> server::getTags(bool useCache) {
return Err(payload.unwrapErr());
}
matjson::Value json = payload.unwrap();
if (!json.is_array()) {
if (!json.isArray()) {
return Err(ServerError(response->code(), "Expected a string array"));
}
std::unordered_set<std::string> tags;
for (auto item : json.as_array()) {
if (!item.is_string()) {
for (auto item : json) {
if (!item.isString()) {
return Err(ServerError(response->code(), "Expected a string array"));
}
tags.insert(item.as_string());
tags.insert(item.asString().unwrap());
}
return Ok(tags);
}

View file

@ -4,7 +4,7 @@
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/web.hpp>
#include <chrono>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <vector>
using namespace geode::prelude;

View file

@ -168,6 +168,19 @@ JsonExpectedValue JsonExpectedValue::has(std::string_view key) {
}
return JsonExpectedValue(m_impl.get(), m_impl->scope[key], key);
}
JsonExpectedValue JsonExpectedValue::hasNullable(std::string_view key) {
if (this->hasError()) {
return JsonExpectedValue();
}
if (!this->assertIs(matjson::Type::Object)) {
return JsonExpectedValue();
}
m_impl->knownKeys.insert(std::string(key));
if (!m_impl->scope.contains(key) || m_impl->scope[key].isNull()) {
return JsonExpectedValue();
}
return JsonExpectedValue(m_impl.get(), m_impl->scope[key], key);
}
JsonExpectedValue JsonExpectedValue::needs(std::string_view key) {
if (this->hasError()) {
return JsonExpectedValue();
@ -190,7 +203,7 @@ std::vector<std::pair<std::string, JsonExpectedValue>> JsonExpectedValue::proper
return std::vector<std::pair<std::string, JsonExpectedValue>>();
}
std::vector<std::pair<std::string, JsonExpectedValue>> res;
for (auto& [k, v] : m_impl->scope.as_object()) {
for (auto& [k, v] : m_impl->scope) {
res.push_back(std::make_pair(k, JsonExpectedValue(m_impl.get(), v, k)));
}
return res;
@ -211,7 +224,7 @@ size_t JsonExpectedValue::length() {
if (!this->assertIs(matjson::Type::Array)) {
return 0;
}
return m_impl->scope.as_array().size();
return m_impl->scope.size();
}
JsonExpectedValue JsonExpectedValue::at(size_t index) {
if (this->hasError()) {
@ -220,15 +233,14 @@ JsonExpectedValue JsonExpectedValue::at(size_t index) {
if (!this->assertIs(matjson::Type::Array)) {
return JsonExpectedValue();
}
auto& arr = m_impl->scope.as_array();
if (arr.size() <= index) {
if (index >= m_impl->scope.size()) {
this->setError(
"array expected to have at least size {}, but its size was only {}",
index + 1, arr.size()
index + 1, m_impl->scope.size()
);
return JsonExpectedValue();
}
return JsonExpectedValue(m_impl.get(), arr.at(index), std::to_string(index));
return JsonExpectedValue(m_impl.get(), m_impl->scope[index], std::to_string(index));
}
std::vector<JsonExpectedValue> JsonExpectedValue::items() {
if (this->hasError()) {
@ -239,7 +251,7 @@ std::vector<JsonExpectedValue> JsonExpectedValue::items() {
}
std::vector<JsonExpectedValue> res;
size_t i = 0;
for (auto& v : m_impl->scope.as_array()) {
for (auto& v : m_impl->scope) {
res.push_back(JsonExpectedValue(m_impl.get(), v, std::to_string(i++)));
}
return res;

View file

@ -4,7 +4,7 @@
#include <Geode/utils/VersionInfo.hpp>
#include <Geode/utils/general.hpp>
#include <matjson3.hpp>
#include <matjson.hpp>
using namespace geode::prelude;

View file

@ -1,6 +1,6 @@
#include <Geode/modify/LoadingLayer.hpp>
#include <Geode/utils/cocos.hpp>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <charconv>
#include <Geode/binding/CCTextInputNode.hpp>
#include <Geode/binding/GameManager.hpp>
@ -32,6 +32,7 @@ Result<cocos2d::ccColor3B, std::string> matjson::Serialize<ccColor3B>::fromJson(
}
return Ok(res.unwrap());
}
return Err("Expected color to be array, object or hex string");
}
matjson::Value matjson::Serialize<ccColor3B>::toJson(cocos2d::ccColor3B const& value) {
return matjson::makeObject({
@ -68,6 +69,7 @@ Result<cocos2d::ccColor4B, std::string> matjson::Serialize<ccColor4B>::fromJson(
}
return Ok(res.unwrap());
}
return Err("Expected color to be array, object or hex string");
}
matjson::Value matjson::Serialize<ccColor4B>::toJson(cocos2d::ccColor4B const& value) {

View file

@ -3,7 +3,7 @@
#include <Geode/utils/file.hpp>
#include <Geode/utils/map.hpp>
#include <Geode/utils/string.hpp>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <fstream>
#include <mz.h>
#include <mz_os.h>
@ -53,14 +53,10 @@ Result<std::string> utils::file::readString(std::filesystem::path const& path) {
}
Result<matjson::Value> utils::file::readJson(std::filesystem::path const& path) {
auto str = utils::file::readString(path);
if (!str)
return Err(str.unwrapErr());
std::string error;
auto res = matjson::parse(str.unwrap(), error);
if (error.size())
return Err("Unable to parse JSON: " + error);
return Ok(res.value());
auto str = GEODE_UNWRAP(utils::file::readString(path));
return matjson::parse(str).mapErr([&](auto const& err) {
return fmt::format("Unable to parse JSON: {}", err);
});
}
Result<ByteVector> utils::file::readBinary(std::filesystem::path const& path) {

View file

@ -3,7 +3,7 @@
#include <filesystem>
#include <fmt/core.h>
#include <fstream>
#include <matjson3.hpp>
#include <matjson.hpp>
#include <system_error>
#define CURL_STATICLIB
#include <curl/curl.h>
@ -130,12 +130,9 @@ Result<std::string> WebResponse::string() const {
}
Result<matjson::Value> WebResponse::json() const {
GEODE_UNWRAP_INTO(auto value, this->string());
std::string error;
auto res = matjson::parse(value, error);
if (error.size() > 0) {
return Err("Error parsing JSON: " + error);
}
return Ok(res.value());
return matjson::parse(value).mapErr([&](auto const& err) {
return fmt::format("Error parsing JSON: {}", err);
});
}
ByteVector WebResponse::data() const {
return m_impl->m_data;
@ -595,7 +592,8 @@ WebRequest& WebRequest::bodyString(std::string_view str) {
}
WebRequest& WebRequest::bodyJSON(matjson::Value const& json) {
this->header("Content-Type", "application/json");
std::string str = json.dump(matjson::NO_INDENTATION);
// TODO: mat
std::string str = json.dump(matjson::NO_INDENTATION).unwrapOr("");
m_impl->m_body = ByteVector { str.begin(), str.end() };
return *this;
}