Mercurial > prosody-hg
comparison teal-src/util/jsonpointer.tl @ 12131:b4c0efff8dd3
util.jsonpointer: Resolve JSON Pointers per RFC 6901
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 29 Dec 2021 16:52:09 +0100 |
| parents | |
| children | 87c3d45208ef |
comparison
equal
deleted
inserted
replaced
| 12130:c4ca226ff386 | 12131:b4c0efff8dd3 |
|---|---|
| 1 | |
| 2 local enum ptr_error | |
| 3 "invalid-table" | |
| 4 "invalid-path" | |
| 5 end | |
| 6 | |
| 7 local function unescape_token(escaped_token : string) : string | |
| 8 local unescaped = escaped_token:gsub("~1", "/"):gsub("~0", "~") | |
| 9 return unescaped | |
| 10 end | |
| 11 | |
| 12 local function resolve_json_pointer(ref : table, path : string) : any, ptr_error | |
| 13 local ptr_len = #path+1 | |
| 14 for part, pos in path:gmatch("/([^/]*)()") do | |
| 15 local token = unescape_token(part) | |
| 16 if not ref is table then | |
| 17 return nil | |
| 18 end | |
| 19 local idx = next(ref) | |
| 20 local new_ref : any | |
| 21 | |
| 22 if idx is string then | |
| 23 new_ref = ref[token] | |
| 24 elseif idx is integer then | |
| 25 local i = tonumber(token) | |
| 26 if token == "-" then i = #ref + 1 end | |
| 27 new_ref = ref[i] | |
| 28 else | |
| 29 return nil, "invalid-table" | |
| 30 end | |
| 31 | |
| 32 if pos as integer == ptr_len then | |
| 33 return new_ref | |
| 34 elseif new_ref is table then | |
| 35 ref = new_ref | |
| 36 elseif not ref is table then | |
| 37 return nil, "invalid-path" | |
| 38 end | |
| 39 | |
| 40 end | |
| 41 return ref | |
| 42 end | |
| 43 | |
| 44 return { | |
| 45 resolve = resolve_json_pointer, | |
| 46 } |
