-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
forgot to add PropertyPartialUpdater.kt.
- Loading branch information
1 parent
48dfdc8
commit eca4b7d
Showing
1 changed file
with
46 additions
and
0 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
.../commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyPartialUpdater.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package dev.atsushieno.ktmidi.ci.propertycommonrules | ||
|
||
import dev.atsushieno.ktmidi.ci.json.Json | ||
|
||
object PropertyPartialUpdater { | ||
fun parseJsonPointer(s: String): List<String> = | ||
if (s.isNotEmpty() && s[0] == '/') | ||
s.substring(1).split('/').map { it.replace("~1", "/").replace("~0", "~") } | ||
else listOf() | ||
|
||
fun applyPartialUpdate(obj: Json.JsonValue, path: String, value: Json.JsonValue): Json.JsonValue = | ||
applyPartialUpdate(obj, parseJsonPointer(path), value) | ||
|
||
fun applyPartialUpdate(obj: Json.JsonValue, jsonPointerPath: List<String>, value: Json.JsonValue): Json.JsonValue = | ||
patch(obj, jsonPointerPath, value) | ||
|
||
private fun patch(obj: Json.JsonValue, path: List<String>, value: Json.JsonValue): Json.JsonValue { | ||
val entry = path.firstOrNull() ?: return obj // path is empty | ||
if (obj.token.type != Json.TokenType.Object) // obj is not an object | ||
return obj | ||
|
||
val contextKey = obj.objectValue.keys.firstOrNull { it.stringValue == entry } | ||
?: return obj // specified path entry does not match | ||
// replace context entry with new object which might be recursively alter the content with the new value | ||
val replacement = if (path.size == 1) value else patch(obj.objectValue[contextKey]!!, path.drop(1), value) | ||
val newMap = obj.objectValue.keys.map { | ||
Pair(it, if (it == contextKey) replacement else obj.objectValue[it]!!) | ||
} | ||
return Json.JsonValue(newMap.toMap()) | ||
} | ||
|
||
fun applyPartialUpdates(existingJson: Json.JsonValue, partialSpecJson: Json.JsonValue): Pair<Boolean, Json.JsonValue> { | ||
val failureReturn = Pair(false, existingJson) | ||
if (partialSpecJson.token.type != Json.TokenType.Object) | ||
return failureReturn // context should be JSON object | ||
|
||
var target = existingJson | ||
// apply all partial updates | ||
partialSpecJson.objectValue.keys.forEach { key -> | ||
val path = if (key.token.type == Json.TokenType.String) key.stringValue else return Pair(false, existingJson) | ||
val newValue = partialSpecJson.objectValue[key]!! | ||
target = applyPartialUpdate(target, path, newValue) | ||
} | ||
return Pair(true, target) | ||
} | ||
} |