Merge pull request #29 from WasabiRaptor/json-patching
improvement to iterating through patch arrays
This commit is contained in:
commit
a6a1cc7f42
@ -678,6 +678,38 @@ ByteArray Assets::read(String const& path) const {
|
|||||||
throw AssetException(strf("No such asset '{}'", path));
|
throw AssetException(strf("No such asset '{}'", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json Assets::checkPatchArray(String const& path, AssetSourcePtr const& source, Json const result, JsonArray const patchData, Maybe<Json> const external) const {
|
||||||
|
auto externalRef = external.value();
|
||||||
|
auto newResult = result;
|
||||||
|
for (auto const patch : patchData) {
|
||||||
|
switch(patch.type()){
|
||||||
|
case Json::Type::Array: // if the patch is an array, go down recursively until we get objects
|
||||||
|
try {
|
||||||
|
newResult = checkPatchArray(path, source, newResult, patch.toArray(), externalRef);
|
||||||
|
} catch (JsonPatchTestFail const& e) {
|
||||||
|
Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", path, source->metadata().value("name", ""), m_assetSourcePaths.getLeft(source), e.what());
|
||||||
|
} catch (JsonPatchException const& e) {
|
||||||
|
Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", path, source->metadata().value("name", ""), m_assetSourcePaths.getLeft(source), e.what());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Json::Type::Object: // if its an object, check for operations, or for if an external file is needed for patches to reference
|
||||||
|
newResult = JsonPatching::applyOperation(newResult, patch, externalRef);
|
||||||
|
break;
|
||||||
|
case Json::Type::String:
|
||||||
|
try {
|
||||||
|
externalRef = json(patch.toString());
|
||||||
|
} catch (...) {
|
||||||
|
throw JsonPatchTestFail(strf("Unable to load reference asset: {}", patch.toString()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw JsonPatchException(strf("Patch data is wrong type: {}", Json::typeName(patch.type())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newResult;
|
||||||
|
}
|
||||||
|
|
||||||
Json Assets::readJson(String const& path) const {
|
Json Assets::readJson(String const& path) const {
|
||||||
ByteArray streamData = read(path);
|
ByteArray streamData = read(path);
|
||||||
try {
|
try {
|
||||||
@ -688,30 +720,13 @@ Json Assets::readJson(String const& path) const {
|
|||||||
if (patchJson.isType(Json::Type::Array)) {
|
if (patchJson.isType(Json::Type::Array)) {
|
||||||
auto patchData = patchJson.toArray();
|
auto patchData = patchJson.toArray();
|
||||||
try {
|
try {
|
||||||
if (patchData.size()) {
|
result = checkPatchArray(pair.first, pair.second, result, patchData, {});
|
||||||
if (patchData.at(0).type() == Json::Type::Array) {
|
|
||||||
for (auto const& patch : patchData) {
|
|
||||||
try {
|
|
||||||
result = jsonPatch(result, patch.toArray());
|
|
||||||
} catch (JsonPatchTestFail const& e) {
|
} catch (JsonPatchTestFail const& e) {
|
||||||
Logger::debug("Patch test failure from file {} in source: {}. Caused by: {}", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, pair.second->metadata().value("name", ""), m_assetSourcePaths.getLeft(pair.second), e.what());
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (patchData.at(0).type() == Json::Type::Object) {
|
|
||||||
try {
|
|
||||||
result = jsonPatch(result, patchData);
|
|
||||||
} catch (JsonPatchTestFail const& e) {
|
|
||||||
Logger::debug("Patch test failure from file {} in source: {}. Caused by: {}", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw JsonPatchException(strf("Patch data is wrong type: {}", Json::typeName(patchData.at(0).type())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JsonPatchException const& e) {
|
} catch (JsonPatchException const& e) {
|
||||||
Logger::error("Could not apply patch from file {} in source: {}. Caused by: {}", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, pair.second->metadata().value("name", ""), m_assetSourcePaths.getLeft(pair.second), e.what());
|
||||||
}
|
}
|
||||||
}
|
} else if (patchJson.isType(Json::Type::Object)) { //Kae: Do a good ol' json merge instead if the .patch file is a Json object
|
||||||
else if (patchJson.isType(Json::Type::Object)) { //Kae: Do a good ol' json merge instead if the .patch file is a Json object
|
|
||||||
auto patchData = patchJson.toObject();
|
auto patchData = patchJson.toObject();
|
||||||
result = jsonMerge(result, patchData);
|
result = jsonMerge(result, patchData);
|
||||||
}
|
}
|
||||||
@ -722,6 +737,7 @@ Json Assets::readJson(String const& path) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Assets::doLoad(AssetId const& id) const {
|
bool Assets::doLoad(AssetId const& id) const {
|
||||||
try {
|
try {
|
||||||
// loadAsset automatically manages the queue and freshens the asset
|
// loadAsset automatically manages the queue and freshens the asset
|
||||||
|
@ -269,6 +269,7 @@ private:
|
|||||||
ByteArray read(String const& basePath) const;
|
ByteArray read(String const& basePath) const;
|
||||||
|
|
||||||
Json readJson(String const& basePath) const;
|
Json readJson(String const& basePath) const;
|
||||||
|
Json checkPatchArray(String const& path, AssetSourcePtr const& source, Json const result, JsonArray const patchData, Maybe<Json> const external) const;
|
||||||
|
|
||||||
// Load / post process an asset and log any exception. Returns true if the
|
// Load / post process an asset and log any exception. Returns true if the
|
||||||
// work was performed (whether successful or not), false if the work is
|
// work was performed (whether successful or not), false if the work is
|
||||||
|
@ -44,7 +44,7 @@ namespace JsonPatching {
|
|||||||
{"merge", std::bind(applyMergeOperation, _1, _2)},
|
{"merge", std::bind(applyMergeOperation, _1, _2)},
|
||||||
};
|
};
|
||||||
|
|
||||||
Json applyOperation(Json const& base, Json const& op) {
|
Json applyOperation(Json const& base, Json const& op, Maybe<Json> const& external) {
|
||||||
try {
|
try {
|
||||||
auto operation = op.getString("op");
|
auto operation = op.getString("op");
|
||||||
return JsonPatching::functionMap.get(operation)(base, op);
|
return JsonPatching::functionMap.get(operation)(base, op);
|
||||||
|
@ -13,7 +13,7 @@ Json jsonPatch(Json const& base, JsonArray const& patch);
|
|||||||
|
|
||||||
namespace JsonPatching {
|
namespace JsonPatching {
|
||||||
// Applies the given single operation
|
// Applies the given single operation
|
||||||
Json applyOperation(Json const& base, Json const& op);
|
Json applyOperation(Json const& base, Json const& op, Maybe<Json> const& external = {});
|
||||||
|
|
||||||
// Tests for "value" at "path"
|
// Tests for "value" at "path"
|
||||||
// Returns base or throws JsonPatchException
|
// Returns base or throws JsonPatchException
|
||||||
|
Loading…
Reference in New Issue
Block a user