mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-11 02:19:30 +00:00
json.match utility procedure
This commit is contained in:
68
core/encoding/json/match.odin
Normal file
68
core/encoding/json/match.odin
Normal file
@@ -0,0 +1,68 @@
|
||||
package encoding_json
|
||||
|
||||
Match_Key_Variant :: union #no_nil {
|
||||
int, // Index
|
||||
string, // Key
|
||||
}
|
||||
|
||||
Match_Error :: enum {
|
||||
None,
|
||||
Invalid_Argument,
|
||||
Invalid_Type_For_Index,
|
||||
Invalid_Type_For_Key,
|
||||
Key_Not_Found,
|
||||
Out_Of_Bounds_Index,
|
||||
}
|
||||
|
||||
Match_Flags :: distinct bit_set[Match_Flag]
|
||||
Match_Flag :: enum {
|
||||
Ignore_Key_Not_Found,
|
||||
Allow_String_Indexing_By_Byte,
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
match :: proc(value: Value, args: ..Match_Key_Variant, flags: Match_Flags = nil) -> (found: Value, err: Match_Error) {
|
||||
found = value
|
||||
arg_loop: for arg in args {
|
||||
switch k in arg {
|
||||
case int:
|
||||
#partial switch v in found {
|
||||
case Array:
|
||||
if 0 <= k && k < len(v) {
|
||||
found = v[k]
|
||||
continue arg_loop
|
||||
}
|
||||
err = .Out_Of_Bounds_Index
|
||||
return
|
||||
case String:
|
||||
if .Allow_String_Indexing_By_Byte in flags {
|
||||
if 0 <= k && k < len(v) {
|
||||
found = Integer(v[k])
|
||||
continue arg_loop
|
||||
}
|
||||
err = .Out_Of_Bounds_Index
|
||||
return
|
||||
}
|
||||
}
|
||||
err = .Invalid_Type_For_Index
|
||||
return
|
||||
case string:
|
||||
v, ok := found.(Object)
|
||||
if !ok {
|
||||
err = .Invalid_Type_For_Key
|
||||
return
|
||||
}
|
||||
vfound, vok := v[k]
|
||||
if vok || (.Ignore_Key_Not_Found in flags) {
|
||||
found = vfound
|
||||
continue arg_loop
|
||||
}
|
||||
err = .Key_Not_Found
|
||||
return
|
||||
case:
|
||||
err = .Invalid_Argument
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user