aboutsummaryrefslogtreecommitdiffstats
path: root/teal-src/util
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-12-29 16:52:09 +0100
committerKim Alvefur <zash@zash.se>2021-12-29 16:52:09 +0100
commitd8017615c75ec62be48d09fa53bbb58e93656c9c (patch)
treec548a8bd62cba7697ad21dd231872a161bd8db72 /teal-src/util
parent9b31c8175eb5a59693295ac40a4b653c7b97207b (diff)
downloadprosody-d8017615c75ec62be48d09fa53bbb58e93656c9c.tar.gz
prosody-d8017615c75ec62be48d09fa53bbb58e93656c9c.zip
util.jsonpointer: Resolve JSON Pointers per RFC 6901
Diffstat (limited to 'teal-src/util')
-rw-r--r--teal-src/util/jsonpointer.tl46
1 files changed, 46 insertions, 0 deletions
diff --git a/teal-src/util/jsonpointer.tl b/teal-src/util/jsonpointer.tl
new file mode 100644
index 00000000..7b9db760
--- /dev/null
+++ b/teal-src/util/jsonpointer.tl
@@ -0,0 +1,46 @@
+
+local enum ptr_error
+ "invalid-table"
+ "invalid-path"
+end
+
+local function unescape_token(escaped_token : string) : string
+ local unescaped = escaped_token:gsub("~1", "/"):gsub("~0", "~")
+ return unescaped
+end
+
+local function resolve_json_pointer(ref : table, path : string) : any, ptr_error
+ local ptr_len = #path+1
+ for part, pos in path:gmatch("/([^/]*)()") do
+ local token = unescape_token(part)
+ if not ref is table then
+ return nil
+ end
+ local idx = next(ref)
+ local new_ref : any
+
+ if idx is string then
+ new_ref = ref[token]
+ elseif idx is integer then
+ local i = tonumber(token)
+ if token == "-" then i = #ref + 1 end
+ new_ref = ref[i]
+ else
+ return nil, "invalid-table"
+ end
+
+ if pos as integer == ptr_len then
+ return new_ref
+ elseif new_ref is table then
+ ref = new_ref
+ elseif not ref is table then
+ return nil, "invalid-path"
+ end
+
+ end
+ return ref
+end
+
+return {
+ resolve = resolve_json_pointer,
+}