Update Json to_text (#1368)

rewrite Json.to_text using fewer allocations
This commit is contained in:
Dmitry Bushev 2020-12-21 17:29:41 +03:00 committed by GitHub
parent 4cc36e8c81
commit 8591784b0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 19 deletions

View File

@ -64,7 +64,7 @@ type Json
## Renders this JSON into an RFC-8259 compliant text.
to_text : Text
to_text = Internal.render_helper this
to_text = Internal.render_helper "" this
## Recursively unwraps the JSON value into primitive values.
unwrap : Any

View File

@ -113,22 +113,34 @@ mk_consumer =
Consumer child val
## Helper method for printing JSON values to Text.
render_helper json = case json of
render_helper builder json = case json of
Object fields ->
fs = fields.to_vector.map item->
key = item.at 0
value = item.at 1
value_json = here.render_helper value
key_json = Printer.json_escape [key]
key_json + ":" + value_json
"{" + (fs.join ",") + "}"
r = Ref.new ""
render_key_value acc key value =
separator = Ref.get r
Ref.put r ","
val = here.render_helper "" value
acc + separator + (Printer.json_escape [key]) + ":" + val
arr = fields.fold_with_key "" render_key_value
builder + "{" + arr + "}"
Array items ->
its = items.map here.render_helper
"[" + (its.join ",") + "]"
String value -> Printer.json_escape [value]
Number value -> value.to_text
Boolean value -> if value then "true" else "false"
Null -> "null"
r = Ref.new ""
render_array_element acc element =
separator = Ref.get r
Ref.put r ","
val = here.render_helper "" element
acc + separator + val
arr = items.fold "" render_array_element
builder + "[" + arr + "]"
String value ->
builder + (Printer.json_escape [value])
Number value ->
builder + value.to_text
Boolean value ->
val = if value then "true" else "false"
builder + val
Null ->
builder + "null"
## Helper method for converting JSON objects into arbitrary types.

View File

@ -163,8 +163,8 @@ type Map
each_with_key function =
go map = case map of
Bin _ k v l r ->
function k v
go l
function k v
go r
Nothing
Tip -> Nothing
@ -174,7 +174,7 @@ type Map
> Example
Summing all of the values in the map `m`.
m.fold (+)
m.fold 0 (+)
fold : Any -> (Any -> Any -> Any) -> Any
fold init function =
go map init = case map of
@ -189,7 +189,7 @@ type Map
> Example
Sum the keys and values in the map `m`.
m.fold_with_key (l -> k -> v -> l + k + v)
m.fold_with_key 0 (l -> k -> v -> l + k + v)
fold_with_key : Any -> (Any -> Any -> Any -> Any) -> Any
fold_with_key init function =
go map init = case map of
@ -235,4 +235,3 @@ type Map
Tip -> Nothing
to_vector_with_builder this
builder.to_vector