diff --git a/core/encoding/json/match.odin b/core/encoding/json/match.odin new file mode 100644 index 000000000..d9598c626 --- /dev/null +++ b/core/encoding/json/match.odin @@ -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 +} \ No newline at end of file