Skip to content

Commit 3552458

Browse files
committed
fix(builtin/json): fix String::to_json()-@json.from_json() round trip
1 parent b986349 commit 3552458

File tree

4 files changed

+39
-44
lines changed

4 files changed

+39
-44
lines changed

builtin/json.mbt

+1-37
Original file line numberDiff line numberDiff line change
@@ -73,45 +73,9 @@ pub fn Float::to_json(self : Float) -> Json {
7373
Number(self.to_double())
7474
}
7575

76-
///|
77-
fn escape_json_string(str : String) -> String {
78-
fn to_hex_digit(i : Int) -> Char {
79-
if i < 10 {
80-
Char::from_int('0'.to_int() + i)
81-
} else {
82-
Char::from_int('a'.to_int() + (i - 10))
83-
}
84-
}
85-
86-
let len = str.length()
87-
let buf = StringBuilder::new(size_hint=len)
88-
for i in 0..<len {
89-
let c = str[i]
90-
match c {
91-
'\n' => buf.write_string("\\n")
92-
'\r' => buf.write_string("\\r")
93-
'\b' => buf.write_string("\\b")
94-
'\t' => buf.write_string("\\t")
95-
_ => {
96-
let code = c.to_int()
97-
if code == 0x0C {
98-
buf.write_string("\\f")
99-
} else if code < 0x20 {
100-
buf.write_string("\\u00")
101-
buf.write_char(to_hex_digit(code / 16))
102-
buf.write_char(to_hex_digit(code % 16))
103-
} else {
104-
buf.write_char(c)
105-
}
106-
}
107-
}
108-
}
109-
buf.to_string()
110-
}
111-
11276
///|
11377
pub fn String::to_json(self : String) -> Json {
114-
String(escape_json_string(self))
78+
String(self)
11579
}
11680

11781
///|

builtin/json_test.mbt

+19-4
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,36 @@ test "test UInt64::to_json" {
104104
test "escape control characters" {
105105
let str = "abc\x01def" // Control character with code 1
106106
let json = str.to_json()
107-
inspect!(json, content="String(\"abc\\\\u0001def\")")
107+
inspect!(
108+
json,
109+
content=
110+
#|String("abc\x01def")
111+
,
112+
)
108113
}
109114

110115
///|
111116
test "test carriage return and backspace" {
112117
let test_string = "CR\rBS\b"
113118
let json = test_string.to_json()
114-
inspect!(json, content="String(\"CR\\\\rBS\\\\b\")")
119+
inspect!(
120+
json,
121+
content=
122+
#|String("CR\rBS\b")
123+
,
124+
)
115125
}
116126

117127
///|
118128
test "test form feed" {
119129
let test_string = "Form\u000CFeed"
120130
let json = test_string.to_json()
121-
inspect!(json, content="String(\"Form\\\\fFeed\")")
131+
inspect!(
132+
json,
133+
content=
134+
#|String("Form\x0cFeed")
135+
,
136+
)
122137
}
123138

124139
///|
@@ -143,7 +158,7 @@ test "Bool::to_json true" {
143158
test "to_hex_digit" {
144159
let str = "\n\r\b\t\x0C\x00"
145160
let escaped = str.to_json().as_string().unwrap()
146-
inspect!(escaped, content="\\n\\r\\b\\t\\f\\u0000")
161+
inspect!(escaped, content="\n\r\b\t\x0c\x00")
147162
}
148163

149164
///|

json/json_test.mbt

+16
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,22 @@ test "stringify escape round trip" {
347347
}
348348
}
349349

350+
///|
351+
test "string from and to json round trip" {
352+
let greeting =
353+
#|
354+
#| (\(\
355+
#| ( -.-)
356+
#| o_(")(")
357+
#| __ __ ____ __ ___ ____ _ __
358+
#| / / / /__ / / /___ / |/ /___ ____ ____ / __ )(_) /_
359+
#| / /_/ / _ \/ / / __ \ / /|_/ / __ \/ __ \/ __ \/ __ / / __/
360+
#| / __ / __/ / / /_/ / / / / / /_/ / /_/ / / / / /_/ / / /_
361+
#| /_/ /_/\___/_/_/\____/ /_/ /_/\____/\____/_/ /_/_____/_/\__/
362+
#|
363+
assert_eq!(@json.from_json!(greeting.to_json()), greeting)
364+
}
365+
350366
///|
351367
test "escape" {
352368
let s = "http://example.com/"

json/to_json_test.mbt

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,19 @@ test "String::to_json" {
102102
inspect!(
103103
"\x00".to_json(),
104104
content=
105-
#|String("\\u0000")
105+
#|String("\x00")
106106
,
107107
)
108108
inspect!(
109109
"\n\r\b\t\\".to_json(),
110110
content=
111-
#|String("\\n\\r\\b\\t\\")
111+
#|String("\n\r\b\t\\")
112112
,
113113
)
114114
inspect!(
115115
"\x0c\x0d\x0f".to_json(),
116116
content=
117-
#|String("\\f\\r\\u000f")
117+
#|String("\x0c\r\x0f")
118118
,
119119
)
120120
}

0 commit comments

Comments
 (0)