sciforge_parser/json/
writer.rs1pub enum JsonVal<'a> {
2 Str(&'a str),
3 Num(f64),
4 Int(i64),
5 Bool(bool),
6 Null,
7 Raw(&'a str),
8}
9
10pub fn write_json_object(fields: &[(&str, JsonVal<'_>)]) -> String {
11 let mut out = String::with_capacity(512);
12 out.push_str("{\n");
13 for (i, (key, val)) in fields.iter().enumerate() {
14 out.push_str(" \"");
15 push_json_escaped(&mut out, key);
16 out.push_str("\": ");
17 push_json_val(&mut out, val);
18 if i + 1 < fields.len() {
19 out.push(',');
20 }
21 out.push('\n');
22 }
23 out.push('}');
24 out
25}
26
27pub fn write_json_array(items: &[String]) -> String {
28 let mut out = String::with_capacity(items.iter().map(|s| s.len() + 2).sum::<usize>() + 4);
29 out.push_str("[\n");
30 for (i, item) in items.iter().enumerate() {
31 out.push_str(item);
32 if i + 1 < items.len() {
33 out.push_str(",\n");
34 }
35 out.push('\n');
36 }
37 out.push(']');
38 out
39}
40
41pub fn push_json_escaped(out: &mut String, s: &str) {
42 for c in s.chars() {
43 match c {
44 '"' => out.push_str("\\\""),
45 '\\' => out.push_str("\\\\"),
46 '\n' => out.push_str("\\n"),
47 '\r' => out.push_str("\\r"),
48 '\t' => out.push_str("\\t"),
49 c if (c as u32) < 0x20 => {
50 out.push_str(&format!("\\u{:04x}", c as u32));
51 }
52 _ => out.push(c),
53 }
54 }
55}
56
57fn push_json_val(out: &mut String, val: &JsonVal<'_>) {
58 match val {
59 JsonVal::Str(s) => {
60 out.push('"');
61 push_json_escaped(out, s);
62 out.push('"');
63 }
64 JsonVal::Num(n) => {
65 if n.fract() == 0.0 && n.abs() < 1e15 {
66 out.push_str(&format!("{}", *n as i64));
67 } else {
68 out.push_str(&format!("{n}"));
69 }
70 }
71 JsonVal::Int(n) => out.push_str(&format!("{n}")),
72 JsonVal::Bool(b) => out.push_str(if *b { "true" } else { "false" }),
73 JsonVal::Null => out.push_str("null"),
74 JsonVal::Raw(s) => out.push_str(s),
75 }
76}