json_event_parser_witespace/
write.rs1#![allow(dead_code)]
2
3use crate::event::JsonEvent;
4use anyhow::Result;
5use std::borrow::Borrow;
6use std::io::Write;
7
8pub struct JsonWriter<W: Write> {
9 writer: W,
10}
11
12impl<W: Write> JsonWriter<W> {
13 pub fn from_writer(writer: W) -> Self {
14 Self { writer }
15 }
16
17 pub fn write_event(&mut self, event: JsonEvent) -> Result<()> {
18 match event {
19 JsonEvent::WhiteSpace(whitespace) => {
20 self.writer.write_all(whitespace.as_bytes())?;
21 }
22 JsonEvent::String(string) => {
23 write_escaped_json_string(string.borrow(), &mut self.writer)?;
24 }
25 JsonEvent::Number(number) => {
26 self.writer.write_all(number.as_bytes())?;
27 }
28 JsonEvent::Boolean(boolean) => {
29 self.writer
30 .write_all(if boolean { b"true" } else { b"false" })?;
31 }
32 JsonEvent::Null => {
33 self.writer.write_all(b"null")?;
34 }
35 JsonEvent::StartObject => {
36 self.writer.write_all(b"{")?;
37 }
38 JsonEvent::NextObjectValue => {
39 self.writer.write_all(b",")?;
40 }
41 JsonEvent::EndObject => {
42 self.writer.write_all(b"}")?;
43 }
44 JsonEvent::ObjectKey(key) => {
45 write_escaped_json_string(key.borrow(), &mut self.writer)?;
46 self.writer.write_all(b":")?;
47 }
48 JsonEvent::StartArray => {
49 self.writer.write_all(b"[")?;
50 }
51 JsonEvent::NextArrayValue => {
52 self.writer.write_all(b",")?;
53 }
54 JsonEvent::EndArray => {
55 self.writer.write_all(b"]")?;
56 }
57 JsonEvent::Eof => {}
58 }
59 Ok(())
60 }
61}
62
63fn write_escaped_json_string(s: &str, sink: &mut impl Write) -> Result<()> {
64 sink.write_all(b"\"")?;
65 let mut buffer = [b'\\', b'u', 0, 0, 0, 0];
66 for c in s.chars() {
67 match c {
68 '\\' => sink.write_all(b"\\\\"),
69 '"' => sink.write_all(b"\\\""),
70 c => {
71 if c < char::from(32) {
72 match c {
73 '\u{08}' => sink.write_all(b"\\b"),
74 '\u{0C}' => sink.write_all(b"\\f"),
75 '\n' => sink.write_all(b"\\n"),
76 '\r' => sink.write_all(b"\\r"),
77 '\t' => sink.write_all(b"\\t"),
78 c => {
79 let mut c = c as u8;
80 for i in (2..6).rev() {
81 let ch = c % 16;
82 buffer[i] = ch + if ch < 10 { b'0' } else { b'A' };
83 c /= 16;
84 }
85 sink.write_all(&buffer)
86 }
87 }
88 } else {
89 sink.write_all(c.encode_utf8(&mut buffer[2..]).as_bytes())
90 }
91 }
92 }?;
93 }
94 sink.write_all(b"\"")?;
95 Ok(())
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::read::JsonReader;
102 use rstest::rstest;
103 use std::borrow::Cow;
104 use std::fs::File;
105 use std::io::{BufReader, Cursor, Read};
106
107 fn write_events(events: Vec<JsonEvent>) -> String {
108 let mut buffer = Vec::new();
109 {
110 let mut writer = JsonWriter::from_writer(&mut buffer);
111 for event in events {
112 writer.write_event(event).unwrap();
113 }
114 }
115
116 String::from_utf8(buffer).unwrap()
117 }
118
119 #[test]
120 fn simple_write() {
121 let events = vec![
122 JsonEvent::StartObject,
123 JsonEvent::ObjectKey(Cow::Owned("key".to_string())),
124 JsonEvent::String(Cow::Owned("value".to_string())),
125 JsonEvent::EndObject,
126 ];
127
128 let json_str = write_events(events);
129 assert_eq!(json_str, "{\"key\":\"value\"}");
130 }
131
132 #[test]
133 fn with_whitespace() {
134 let events = vec![
135 JsonEvent::WhiteSpace("\n ".to_string()),
136 JsonEvent::StartObject,
137 JsonEvent::ObjectKey(Cow::Owned("key".to_string())),
138 JsonEvent::String(Cow::Owned("value".to_string())),
139 JsonEvent::EndObject,
140 ];
141
142 let json_str = write_events(events);
143 assert_eq!(json_str, "\n {\"key\":\"value\"}");
144 }
145
146 #[rstest]
147 fn read_and_write(
148 #[values(
149 " {\"key\": \"value\" \n, \"key2\": 123} ",
150 " [ 1 , 2 , 3] "
151 )]
152 json_str: &str,
153 ) {
154 let mut reader = JsonReader::from_reader(BufReader::new(Cursor::new(json_str.as_bytes())));
155 let mut output_json_buffer = vec![];
156 {
157 let mut writer = JsonWriter::from_writer(&mut output_json_buffer);
158
159 let mut buffer = vec![];
160 loop {
161 let event = reader.read_event(&mut buffer).unwrap();
162 dbg!(&event);
163 if event == JsonEvent::Eof {
164 break;
165 }
166 writer.write_event(event).unwrap();
167 }
168 }
169 let output_json_str = String::from_utf8(output_json_buffer).unwrap();
170
171 assert_eq!(output_json_str, json_str);
172 }
173
174 #[test]
175 fn read_and_write_realcase() {
176 let mut buf = String::new();
177 File::open("assets/notebook/sample.ipynb")
178 .unwrap()
179 .read_to_string(&mut buf)
180 .unwrap();
181
182 let mut reader = JsonReader::from_reader(BufReader::new(Cursor::new(buf.as_bytes())));
183 let mut output_json_buffer = vec![];
184 {
185 let mut writer = JsonWriter::from_writer(&mut output_json_buffer);
186
187 let mut buffer = vec![];
188 loop {
189 let event = reader.read_event(&mut buffer).unwrap();
190 dbg!(&event);
191 if event == JsonEvent::Eof {
192 break;
193 }
194 writer.write_event(event).unwrap();
195 }
196 }
197 let output_json_str = String::from_utf8(output_json_buffer).unwrap();
198
199 assert_eq!(output_json_str, buf);
200 }
201}