Skip to content

Commit 656a2af

Browse files
Elly Jonesbrson
Elly Jones
authored andcommitted
json: betterify for brson
Signed-off-by: Elly Jones <[email protected]>
1 parent bd72626 commit 656a2af

File tree

4 files changed

+106
-93
lines changed

4 files changed

+106
-93
lines changed

src/lib/json.rs

Lines changed: 50 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
#[link(name = "json",
2-
vers = "0.1",
3-
uuid = "09d7f2fc-1fad-48b2-9f9d-a65512342f16",
4-
url = "http://www.leptoquark.net/~elly/rust/")];
5-
#[copyright = "Google Inc. 2011"];
6-
#[comment = "JSON serialization format library"];
7-
#[license = "BSD"];
1+
// Rust JSON serialization library
2+
// Copyright (c) 2011 Google Inc.
83

94
import float;
105
import map;
@@ -14,18 +9,39 @@ import str;
149
import vec;
1510

1611
export json;
17-
export tostr;
18-
export fromstr;
12+
export to_str;
13+
export from_str;
1914

15+
export num;
16+
export string;
17+
export boolean;
18+
export list;
19+
export dict;
20+
21+
/*
22+
Tag: json
23+
24+
Represents a json value.
25+
*/
2026
tag json {
27+
/* Variant: num */
2128
num(float);
29+
/* Variant: string */
2230
string(str);
31+
/* Variant: boolean */
2332
boolean(bool);
33+
/* Variant: list */
2434
list(@[json]);
35+
/* Variant: dict */
2536
dict(map::hashmap<str,json>);
2637
}
2738

28-
fn tostr(j: json) -> str {
39+
/*
40+
Function: to_str
41+
42+
Serializes a json value into a string.
43+
*/
44+
fn to_str(j: json) -> str {
2945
alt j {
3046
num(f) { float::to_str(f, 6u) }
3147
string(s) { #fmt["\"%s\"", s] } // XXX: escape
@@ -34,15 +50,15 @@ fn tostr(j: json) -> str {
3450
list(@js) {
3551
str::concat(["[",
3652
str::connect(
37-
vec::map::<json,str>({ |e| tostr(e) }, js),
53+
vec::map::<json,str>({ |e| to_str(e) }, js),
3854
", "),
3955
"]"])
4056
}
4157
dict(m) {
4258
let parts = [];
4359
m.items({ |k, v|
4460
vec::grow(parts, 1u,
45-
str::concat(["\"", k, "\": ", tostr(v)])
61+
str::concat(["\"", k, "\": ", to_str(v)])
4662
)
4763
});
4864
str::concat(["{ ", str::connect(parts, ", "), " }"])
@@ -51,10 +67,11 @@ fn tostr(j: json) -> str {
5167
}
5268

5369
fn rest(s: str) -> str {
70+
assert(str::char_len(s) >= 1u);
5471
str::char_slice(s, 1u, str::char_len(s))
5572
}
5673

57-
fn fromstr_str(s: str) -> (option::t<json>, str) {
74+
fn from_str_str(s: str) -> (option::t<json>, str) {
5875
let pos = 0u;
5976
let len = str::byte_len(s);
6077
let escape = false;
@@ -86,15 +103,15 @@ fn fromstr_str(s: str) -> (option::t<json>, str) {
86103
ret (none, s);
87104
}
88105

89-
fn fromstr_list(s: str) -> (option::t<json>, str) {
106+
fn from_str_list(s: str) -> (option::t<json>, str) {
90107
if str::char_at(s, 0u) != '[' { ret (none, s); }
91108
let s0 = str::trim_left(rest(s));
92109
let vals = [];
93110
if str::is_empty(s0) { ret (none, s0); }
94111
if str::char_at(s0, 0u) == ']' { ret (some(list(@[])), rest(s0)); }
95112
while str::is_not_empty(s0) {
96113
s0 = str::trim_left(s0);
97-
let (next, s1) = fromstr_helper(s0);
114+
let (next, s1) = from_str_helper(s0);
98115
s0 = s1;
99116
alt next {
100117
some(j) { vec::grow(vals, 1u, j); }
@@ -112,15 +129,15 @@ fn fromstr_list(s: str) -> (option::t<json>, str) {
112129
ret (none, s0);
113130
}
114131

115-
fn fromstr_dict(s: str) -> (option::t<json>, str) {
132+
fn from_str_dict(s: str) -> (option::t<json>, str) {
116133
if str::char_at(s, 0u) != '{' { ret (none, s); }
117134
let s0 = str::trim_left(rest(s));
118135
let vals = map::new_str_hash::<json>();
119136
if str::is_empty(s0) { ret (none, s0); }
120137
if str::char_at(s0, 0u) == '}' { ret (some(dict(vals)), rest(s0)); }
121138
while str::is_not_empty(s0) {
122139
s0 = str::trim_left(s0);
123-
let (next, s1) = fromstr_helper(s0); // key
140+
let (next, s1) = from_str_helper(s0); // key
124141
let key = "";
125142
s0 = s1;
126143
alt next {
@@ -131,7 +148,7 @@ fn fromstr_dict(s: str) -> (option::t<json>, str) {
131148
if str::is_empty(s0) { ret (none, s0); }
132149
if str::char_at(s0, 0u) != ':' { ret (none, s0); }
133150
s0 = str::trim_left(rest(s0));
134-
let (next, s1) = fromstr_helper(s0); // value
151+
let (next, s1) = from_str_helper(s0); // value
135152
s0 = s1;
136153
alt next {
137154
some(j) { vals.insert(key, j); }
@@ -149,7 +166,7 @@ fn fromstr_dict(s: str) -> (option::t<json>, str) {
149166
(none, s)
150167
}
151168

152-
fn fromstr_float(s: str) -> (option::t<json>, str) {
169+
fn from_str_float(s: str) -> (option::t<json>, str) {
153170
let pos = 0u;
154171
let len = str::byte_len(s);
155172
let res = 0f;
@@ -205,7 +222,7 @@ fn fromstr_float(s: str) -> (option::t<json>, str) {
205222
ret (some(num(neg * res)), str::char_slice(s, pos, str::char_len(s)));
206223
}
207224

208-
fn fromstr_bool(s: str) -> (option::t<json>, str) {
225+
fn from_str_bool(s: str) -> (option::t<json>, str) {
209226
if (str::starts_with(s, "true")) {
210227
(some(boolean(true)), str::slice(s, 4u, str::byte_len(s)))
211228
} else if (str::starts_with(s, "false")) {
@@ -215,79 +232,26 @@ fn fromstr_bool(s: str) -> (option::t<json>, str) {
215232
}
216233
}
217234

218-
fn fromstr_helper(s: str) -> (option::t<json>, str) {
235+
fn from_str_helper(s: str) -> (option::t<json>, str) {
219236
let s = str::trim_left(s);
220237
if str::is_empty(s) { ret (none, s); }
221238
let start = str::char_at(s, 0u);
222239
alt start {
223-
'"' { fromstr_str(s) }
224-
'[' { fromstr_list(s) }
225-
'{' { fromstr_dict(s) }
226-
'0' to '9' | '-' | '+' | '.' { fromstr_float(s) }
227-
't' | 'f' { fromstr_bool(s) }
240+
'"' { from_str_str(s) }
241+
'[' { from_str_list(s) }
242+
'{' { from_str_dict(s) }
243+
'0' to '9' | '-' | '+' | '.' { from_str_float(s) }
244+
't' | 'f' { from_str_bool(s) }
228245
_ { ret (none, s); }
229246
}
230247
}
231248

232-
fn fromstr(s: str) -> option::t<json> {
233-
let (j, _) = fromstr_helper(s);
234-
j
235-
}
236-
237-
fn main() {
238-
let j = fromstr("{ \"foo\": [ 4, 5 ], \"bar\": { \"baz\": true}}");
239-
alt j {
240-
some(j0) {
241-
log tostr(j0);
242-
}
243-
_ { }
244-
}
245-
}
246-
247-
#[cfg(test)]
248-
mod tests {
249-
#[test]
250-
fn test_fromstr_num() {
251-
assert(fromstr("3") == some(num(3f)));
252-
assert(fromstr("3.1") == some(num(3.1f)));
253-
assert(fromstr("-1.2") == some(num(-1.2f)));
254-
assert(fromstr(".4") == some(num(0.4f)));
255-
}
256-
257-
#[test]
258-
fn test_fromstr_str() {
259-
assert(fromstr("\"foo\"") == some(string("foo")));
260-
assert(fromstr("\"\\\"\"") == some(string("\"")));
261-
assert(fromstr("\"lol") == none);
262-
}
263-
264-
#[test]
265-
fn test_fromstr_bool() {
266-
assert(fromstr("true") == some(boolean(true)));
267-
assert(fromstr("false") == some(boolean(false)));
268-
assert(fromstr("truz") == none);
269-
}
270-
271-
#[test]
272-
fn test_fromstr_list() {
273-
assert(fromstr("[]") == some(list(@[])));
274-
assert(fromstr("[true]") == some(list(@[boolean(true)])));
275-
assert(fromstr("[3, 1]") == some(list(@[num(3f), num(1f)])));
276-
assert(fromstr("[2, [4, 1]]") ==
277-
some(list(@[num(2f), list(@[num(4f), num(1f)])])));
278-
assert(fromstr("[2, ]") == none);
279-
assert(fromstr("[5, ") == none);
280-
assert(fromstr("[6 7]") == none);
281-
assert(fromstr("[3") == none);
282-
}
249+
/*
250+
Function: from_str
283251
284-
#[test]
285-
fn test_fromstr_dict() {
286-
assert(fromstr("{}") != none);
287-
assert(fromstr("{\"a\": 3}") != none);
288-
assert(fromstr("{\"a\": }") == none);
289-
assert(fromstr("{\"a\" }") == none);
290-
assert(fromstr("{\"a\"") == none);
291-
assert(fromstr("{") == none);
292-
}
252+
Deserializes a json value from a string.
253+
*/
254+
fn from_str(s: str) -> option::t<json> {
255+
let (j, _) = from_str_helper(s);
256+
j
293257
}

src/lib/std.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export aio, comm, fs, io, net, run, sio, sys, task;
1212
export ctypes, either, option, result, util;
1313
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
1414
export rope;
15-
export ebml, dbg, getopts, math, rand, sha1, term, time, unsafe;
15+
export ebml, dbg, getopts, json, math, rand, sha1, term, time, unsafe;
1616
export extfmt, test;
1717
// FIXME: generic_os and os_fs shouldn't be exported
1818
export generic_os, os, os_fs;

src/test/stdtest/json.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std;
2+
import std::json::*;
3+
import std::option::{none, some};
4+
5+
#[test]
6+
fn test_from_str_num() {
7+
assert(from_str("3") == some(num(3f)));
8+
assert(from_str("3.1") == some(num(3.1f)));
9+
assert(from_str("-1.2") == some(num(-1.2f)));
10+
assert(from_str(".4") == some(num(0.4f)));
11+
}
12+
13+
#[test]
14+
fn test_from_str_str() {
15+
assert(from_str("\"foo\"") == some(string("foo")));
16+
assert(from_str("\"\\\"\"") == some(string("\"")));
17+
assert(from_str("\"lol") == none);
18+
}
19+
20+
#[test]
21+
fn test_from_str_bool() {
22+
assert(from_str("true") == some(boolean(true)));
23+
assert(from_str("false") == some(boolean(false)));
24+
assert(from_str("truz") == none);
25+
}
26+
27+
#[test]
28+
fn test_from_str_list() {
29+
assert(from_str("[]") == some(list(@[])));
30+
assert(from_str("[true]") == some(list(@[boolean(true)])));
31+
assert(from_str("[3, 1]") == some(list(@[num(3f), num(1f)])));
32+
assert(from_str("[2, [4, 1]]") ==
33+
some(list(@[num(2f), list(@[num(4f), num(1f)])])));
34+
assert(from_str("[2, ]") == none);
35+
assert(from_str("[5, ") == none);
36+
assert(from_str("[6 7]") == none);
37+
assert(from_str("[3") == none);
38+
}
39+
40+
#[test]
41+
fn test_from_str_dict() {
42+
assert(from_str("{}") != none);
43+
assert(from_str("{\"a\": 3}") != none);
44+
assert(from_str("{\"a\": }") == none);
45+
assert(from_str("{\"a\" }") == none);
46+
assert(from_str("{\"a\"") == none);
47+
assert(from_str("{") == none);
48+
}

src/test/stdtest/stdtest.rc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ mod char;
66
mod comm;
77
mod deque;
88
mod either;
9+
mod float;
910
mod fs;
1011
mod getopts;
1112
mod int;
1213
mod io;
13-
mod vec;
14+
mod json;
1415
mod list;
1516
mod map;
16-
mod treemap;
17+
mod math;
1718
mod net;
1819
mod option;
1920
mod os;
@@ -22,18 +23,18 @@ mod ptr;
2223
mod qsort3;
2324
mod qsort;
2425
mod rand;
26+
mod result;
27+
mod rope;
2528
mod run;
2629
mod sha1;
2730
mod sort;
2831
mod str;
2932
mod sys;
3033
mod task;
3134
mod test;
35+
mod treemap;
3236
mod uint;
33-
mod float;
34-
mod math;
35-
mod result;
36-
mod rope;
37+
mod vec;
3738

3839
// Local Variables:
3940
// mode: rust

0 commit comments

Comments
 (0)