mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-11 10:29:32 +00:00
68 lines
1.3 KiB
Odin
68 lines
1.3 KiB
Odin
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
|
|
} |