From 14ee2181cbf270863d0aa7e1be36814c1ded1354 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:42:11 +1000 Subject: [PATCH 01/10] Fix bug https://github.com/odin-lang/Odin/issues/3173 --- core/encoding/json/marshal.odin | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e9285364b..da250dc01 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -377,6 +377,15 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: opt_write_end(w, opt, '}') or_return case runtime.Type_Info_Union: + // check for empty unions + if len(info.variants) == 0 { + io.write_string(w, "null") or_return + return + } + if info.tag_type == nil { + panic("Union tag type is nil.") + } + tag_ptr := uintptr(v.data) + info.tag_offset tag_any := any{rawptr(tag_ptr), info.tag_type.id} From 7e0473dded188a18a19f5fc4aa9b45bc31934e0e Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:03:15 +1000 Subject: [PATCH 02/10] Revert json union fix --- core/encoding/json/marshal.odin | 9 --------- 1 file changed, 9 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index da250dc01..e9285364b 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -377,15 +377,6 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: opt_write_end(w, opt, '}') or_return case runtime.Type_Info_Union: - // check for empty unions - if len(info.variants) == 0 { - io.write_string(w, "null") or_return - return - } - if info.tag_type == nil { - panic("Union tag type is nil.") - } - tag_ptr := uintptr(v.data) + info.tag_offset tag_any := any{rawptr(tag_ptr), info.tag_type.id} From b2b8b14955e680543fecbbf397fc949b1ce121cf Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:07:03 +1000 Subject: [PATCH 03/10] Add better support for Enums in json Can now output enum value's name instead of its underlineing value --- core/encoding/json/marshal.odin | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e9285364b..d3d046b33 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -51,6 +51,9 @@ Marshal_Options :: struct { // NOTE: This will temp allocate and sort a list for each map. sort_maps_by_key: bool, + // Output enum value's name instead of its underlineing value + use_enum_value_names: bool + // Internal state indentation: int, mjson_skipped_first_braces_start: bool, @@ -401,7 +404,24 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: } case runtime.Type_Info_Enum: - return marshal_to_writer(w, any{v.data, info.base.id}, opt) + if !opt.use_enum_value_names || len(info.names) == 0 { + return marshal_to_writer(w, any{v.data, info.base.id}, opt) + } else { + enum_a := any{v.data, info.base.id} + u: runtime.Type_Info_Enum_Value + + switch i in enum_a { + case int: u = runtime.Type_Info_Enum_Value(i) + case: panic("Invalid enum base type") + } + + pos, found := slice.binary_search(info.values, u) + if found { + return marshal_to_writer(w, any(info.names[pos]), opt) + } else { + panic("Unable to find value in enum's values") + } + } case runtime.Type_Info_Bit_Set: is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool { From b39ef29ec62a504fb3c46c1375a4b801dab292ef Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:15:35 +1000 Subject: [PATCH 04/10] add missing comma --- core/encoding/json/marshal.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index d3d046b33..9433d525e 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -52,7 +52,7 @@ Marshal_Options :: struct { sort_maps_by_key: bool, // Output enum value's name instead of its underlineing value - use_enum_value_names: bool + use_enum_value_names: bool, // Internal state indentation: int, From c276b1c0bc50e3f66a8003ade48a79c669122dc7 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:51:29 +1000 Subject: [PATCH 05/10] replace spaces with tabs --- core/encoding/json/marshal.odin | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 9433d525e..f544070b2 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -51,8 +51,8 @@ Marshal_Options :: struct { // NOTE: This will temp allocate and sort a list for each map. sort_maps_by_key: bool, - // Output enum value's name instead of its underlineing value - use_enum_value_names: bool, + // Output enum value's name instead of its underlineing value + use_enum_value_names: bool, // Internal state indentation: int, @@ -405,23 +405,23 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Enum: if !opt.use_enum_value_names || len(info.names) == 0 { - return marshal_to_writer(w, any{v.data, info.base.id}, opt) - } else { - enum_a := any{v.data, info.base.id} - u: runtime.Type_Info_Enum_Value + return marshal_to_writer(w, any{v.data, info.base.id}, opt) + } else { + enum_a := any{v.data, info.base.id} + u: runtime.Type_Info_Enum_Value - switch i in enum_a { - case int: u = runtime.Type_Info_Enum_Value(i) - case: panic("Invalid enum base type") - } + switch i in enum_a { + case int: u = runtime.Type_Info_Enum_Value(i) + case: panic("Invalid enum base type") + } - pos, found := slice.binary_search(info.values, u) - if found { - return marshal_to_writer(w, any(info.names[pos]), opt) - } else { - panic("Unable to find value in enum's values") - } - } + pos, found := slice.binary_search(info.values, u) + if found { + return marshal_to_writer(w, any(info.names[pos]), opt) + } else { + panic("Unable to find value in enum's values") + } + } case runtime.Type_Info_Bit_Set: is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool { From a95cead8e7dfb747cc5afa58dc8f1a76966d035b Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:05:50 +1000 Subject: [PATCH 06/10] add all inter types to switch --- core/encoding/json/marshal.odin | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index f544070b2..78ba4bea4 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -411,11 +411,35 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: u: runtime.Type_Info_Enum_Value switch i in enum_a { - case int: u = runtime.Type_Info_Enum_Value(i) - case: panic("Invalid enum base type") + case i8: u = runtime.Type_Info_Enum_Value(i) + case i16: u = runtime.Type_Info_Enum_Value(i) + case i32: u = runtime.Type_Info_Enum_Value(i) + case i64: u = runtime.Type_Info_Enum_Value(i) + case int: u = runtime.Type_Info_Enum_Value(i) + case u8: u = runtime.Type_Info_Enum_Value(i) + case u16: u = runtime.Type_Info_Enum_Value(i) + case u32: u = runtime.Type_Info_Enum_Value(i) + case u64: u = runtime.Type_Info_Enum_Value(i) + case uint: u = runtime.Type_Info_Enum_Value(i) + case uintptr: u = runtime.Type_Info_Enum_Value(i) + + case i16le: u = runtime.Type_Info_Enum_Value(i) + case i32le: u = runtime.Type_Info_Enum_Value(i) + case i64le: u = runtime.Type_Info_Enum_Value(i) + case u16le: u = runtime.Type_Info_Enum_Value(i) + case u32le: u = runtime.Type_Info_Enum_Value(i) + case u64le: u = runtime.Type_Info_Enum_Value(i) + + case i16be: u = runtime.Type_Info_Enum_Value(i) + case i32be: u = runtime.Type_Info_Enum_Value(i) + case i64be: u = runtime.Type_Info_Enum_Value(i) + case u16be: u = runtime.Type_Info_Enum_Value(i) + case u32be: u = runtime.Type_Info_Enum_Value(i) + case u64be: u = runtime.Type_Info_Enum_Value(i) + case: panic("Invalid enum base type") } - pos, found := slice.binary_search(info.values, u) + pos, found := slice.linear_search(info.values, u) if found { return marshal_to_writer(w, any(info.names[pos]), opt) } else { From 41fbaaf1d3caf341f556fdf24fa63471f1a6d3c0 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Fri, 1 Mar 2024 14:53:39 +1000 Subject: [PATCH 07/10] changed to use reflect.enum_name_from_value_any --- core/encoding/json/marshal.odin | 36 ++------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 7b0e74c69..95ca038f3 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -410,41 +410,9 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: if !opt.use_enum_value_names || len(info.names) == 0 { return marshal_to_writer(w, any{v.data, info.base.id}, opt) } else { - enum_a := any{v.data, info.base.id} - u: runtime.Type_Info_Enum_Value - - switch i in enum_a { - case i8: u = runtime.Type_Info_Enum_Value(i) - case i16: u = runtime.Type_Info_Enum_Value(i) - case i32: u = runtime.Type_Info_Enum_Value(i) - case i64: u = runtime.Type_Info_Enum_Value(i) - case int: u = runtime.Type_Info_Enum_Value(i) - case u8: u = runtime.Type_Info_Enum_Value(i) - case u16: u = runtime.Type_Info_Enum_Value(i) - case u32: u = runtime.Type_Info_Enum_Value(i) - case u64: u = runtime.Type_Info_Enum_Value(i) - case uint: u = runtime.Type_Info_Enum_Value(i) - case uintptr: u = runtime.Type_Info_Enum_Value(i) - - case i16le: u = runtime.Type_Info_Enum_Value(i) - case i32le: u = runtime.Type_Info_Enum_Value(i) - case i64le: u = runtime.Type_Info_Enum_Value(i) - case u16le: u = runtime.Type_Info_Enum_Value(i) - case u32le: u = runtime.Type_Info_Enum_Value(i) - case u64le: u = runtime.Type_Info_Enum_Value(i) - - case i16be: u = runtime.Type_Info_Enum_Value(i) - case i32be: u = runtime.Type_Info_Enum_Value(i) - case i64be: u = runtime.Type_Info_Enum_Value(i) - case u16be: u = runtime.Type_Info_Enum_Value(i) - case u32be: u = runtime.Type_Info_Enum_Value(i) - case u64be: u = runtime.Type_Info_Enum_Value(i) - case: panic("Invalid enum base type") - } - - pos, found := slice.linear_search(info.values, u) + name, found := reflect.enum_name_from_value_any(v) if found { - return marshal_to_writer(w, any(info.names[pos]), opt) + return marshal_to_writer(w, name, opt) } else { panic("Unable to find value in enum's values") } From 9070e613a44059f5bd1b77277de74a1f549f7369 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:06:30 +1000 Subject: [PATCH 08/10] Return underlining value instead of panicing when no name it found. Renamed use_enum_value_names to use_enum_names it get the same point across & inline with the reflect procs --- core/encoding/json/marshal.odin | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 95ca038f3..2a052dbd9 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -51,8 +51,10 @@ Marshal_Options :: struct { // NOTE: This will temp allocate and sort a list for each map. sort_maps_by_key: bool, - // Output enum value's name instead of its underlineing value - use_enum_value_names: bool, + // Output enum value's name instead of its underlineing value. + // + // NOTE: If a name isn't found it'll use the underlineing value. + use_enum_names: bool, // Internal state indentation: int, @@ -407,14 +409,14 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: } case runtime.Type_Info_Enum: - if !opt.use_enum_value_names || len(info.names) == 0 { + if !opt.use_enum_names || len(info.names) == 0 { return marshal_to_writer(w, any{v.data, info.base.id}, opt) } else { name, found := reflect.enum_name_from_value_any(v) if found { return marshal_to_writer(w, name, opt) } else { - panic("Unable to find value in enum's values") + return marshal_to_writer(w, any{v.data, info.base.id}, opt) } } From 116edb9052b9d16d3d286b6ada42b053260ba424 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:09:17 +1000 Subject: [PATCH 09/10] convert spaces to tabs --- core/encoding/json/marshal.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 2a052dbd9..8b3a2bd56 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -53,7 +53,7 @@ Marshal_Options :: struct { // Output enum value's name instead of its underlineing value. // - // NOTE: If a name isn't found it'll use the underlineing value. + // NOTE: If a name isn't found it'll use the underlineing value. use_enum_names: bool, // Internal state From b419615002e55e968c2caf2319df5044effc90c4 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:20:13 +1000 Subject: [PATCH 10/10] Apply suggestions from code review Fixing spelling mistakes pointed out & fixed by layton. Co-authored-by: Laytan --- core/encoding/json/marshal.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 8b3a2bd56..6440e3b30 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -51,9 +51,9 @@ Marshal_Options :: struct { // NOTE: This will temp allocate and sort a list for each map. sort_maps_by_key: bool, - // Output enum value's name instead of its underlineing value. + // Output enum value's name instead of its underlying value. // - // NOTE: If a name isn't found it'll use the underlineing value. + // NOTE: If a name isn't found it'll use the underlying value. use_enum_names: bool, // Internal state