From 311e46962f3e5a39039a44870e2898aa34e4f7f0 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 18 Jun 2021 19:55:43 -0500 Subject: [PATCH] added basic json encoding --- modules/json/encoder.onyx | 122 +++++++++++++++++++++++++++++++++++++- modules/json/example.onyx | 7 ++- modules/json/parser.onyx | 2 +- 3 files changed, 127 insertions(+), 4 deletions(-) diff --git a/modules/json/encoder.onyx b/modules/json/encoder.onyx index 09d59843..eb08922b 100644 --- a/modules/json/encoder.onyx +++ b/modules/json/encoder.onyx @@ -1 +1,121 @@ -package json \ No newline at end of file +package json + +use package core + +Encoding_Error :: enum { + None; + Unsupported_Type; +} + +encode_string :: (v: $T, allocator := context.allocator) -> (str, Encoding_Error) { + stream := io.dynamic_string_stream_make(256); + writer := io.writer_make(^stream); + defer io.dynamic_string_stream_free(^stream); + + err := encode(^writer, v); + if err != .None { + return "", err; + } + + s := string.alloc_copy(io.dynamic_string_stream_to_str(^stream), allocator); + return s, .None; +} + +encode :: #match { + (w: ^io.Writer, v: i32) -> Encoding_Error { + io.write_i32(w, ~~v); + return .None; + }, + + (w: ^io.Writer, v: i64) -> Encoding_Error { + io.write_i64(w, ~~v); + return .None; + }, + + (w: ^io.Writer, v: f32) -> Encoding_Error { + io.write_f32(w, ~~v); + return .None; + }, + + (w: ^io.Writer, v: f64) -> Encoding_Error { + io.write_f64(w, ~~v); + return .None; + }, + + (w: ^io.Writer, v: str) -> Encoding_Error { + io.write_escaped_str(w, v); + return .None; + }, + + (w: ^io.Writer, v: [..] $T) -> Encoding_Error { + io.write_byte(w, #char "["); + + for i: v.count { + if i > 0 do io.write_byte(w, #char ","); + + err := encode(w, v[i]); + if err != .None do return err; + } + + io.write_byte(w, #char "]"); + return .None; + }, + + (w: ^io.Writer, v: map.Map(str, $T)) -> Encoding_Error { + io.write_byte(w, #char "{"); + + for i: v.entries.count { + if i > 0 do io.write_byte(w, #char ","); + entry := v.entries[i]; + + io.write_escaped_str(w, entry.key); + io.write_byte(w, #char ":"); + + err := encode(w, entry.value); + if err != .None do return err; + } + + io.write_byte(w, #char "}"); + return .None; + }, + + (w: ^io.Writer, v: ^Value) -> Encoding_Error { + switch v.type { + case .Null do io.write_str(w, "null"); + case .Bool do io.write(w, v->as_bool()); + case .Integer do io.write(w, v->as_int()); + case .Float do io.write(w, v->as_float()); + case .String do encode(w, v->as_str()); + case .Array do encode(w, v->as_array()); + + case .Object { + io.write_byte(w, #char "{"); + obj := cast(^Value_Object) v; + + for i: obj.object_.count { + if i > 0 do io.write_byte(w, #char ","); + + io.write_escaped_str(w, obj.object_[i].key); + io.write_byte(w, #char ":"); + + err := encode(w, obj.object_[i].value); + if err != .None do return err; + } + + io.write_byte(w, #char "}"); + } + + case #default { + return .Unsupported_Type; + } + } + + return .None; + }, + + + // Inserted after any of the #add_match directives + #precedence 1000 (w: ^io.Writer, v: $T) -> Encoding_Error { + return .Unsupported_Type; + } +} \ No newline at end of file diff --git a/modules/json/example.onyx b/modules/json/example.onyx index 96ba62d4..d45297c4 100644 --- a/modules/json/example.onyx +++ b/modules/json/example.onyx @@ -5,7 +5,7 @@ use package core json :: package json -json_string := "{ \"test\": \"\\tHello,\\nWorld!\", \"array\": [1,2,3,4,5,1423], \"sub\": { \"mem\": true } }"; +json_string := "{ \"test\": \"\\tHello,\\n\\\"World!\\\"\", \"array\": [1,2,3,4,5,1423], \"sub\": { \"mem\": true } }"; main :: (args: [] cstr) { arena := alloc.arena.make(context.allocator, 4096); @@ -20,7 +20,7 @@ main :: (args: [] cstr) { // println(v["friends"][1]["name"]->as_str()); // } - #if true { + #if false { value := decoded_json.root["array"]; for v: value->as_array() { println(v->as_int()); @@ -30,5 +30,8 @@ main :: (args: [] cstr) { decoded_json.root["test"]->as_str() |> println(); } + + json.encode(^stdio.print_writer, decoded_json.root); + print("\n"); } \ No newline at end of file diff --git a/modules/json/parser.onyx b/modules/json/parser.onyx index 25741d23..52edaa65 100644 --- a/modules/json/parser.onyx +++ b/modules/json/parser.onyx @@ -208,7 +208,7 @@ parse_object :: (use parser: ^Parser) -> (^Value_Object, Error) { array.push(^value.object_, .{ key = key, - value = elem + value = elem }); if !consume_token_if_next(parser, .Comma) { -- 2.25.1