1
1
use crate :: JsonEvent ;
2
2
use std:: io:: { Error , ErrorKind , Result , Write } ;
3
+ #[ cfg( feature = "async-tokio" ) ]
4
+ use tokio:: io:: { AsyncWrite , AsyncWriteExt } ;
3
5
4
- /// A JSON streaming writer.
6
+ /// A JSON streaming writer writing to a [`Write`] implementation .
5
7
///
6
8
/// ```
7
- /// use json_event_parser::{JsonWriter , JsonEvent};
9
+ /// use json_event_parser::{ToWriteJsonWriter , JsonEvent};
8
10
///
9
- /// let mut buffer = Vec::new();
10
- /// let mut writer = JsonWriter::from_writer(&mut buffer);
11
+ /// let mut writer = ToWriteJsonWriter::new(Vec::new());
11
12
/// writer.write_event(JsonEvent::StartObject)?;
12
13
/// writer.write_event(JsonEvent::ObjectKey("foo".into()))?;
13
14
/// writer.write_event(JsonEvent::Number("1".into()))?;
14
15
/// writer.write_event(JsonEvent::EndObject)?;
15
16
///
16
- /// assert_eq!(buffer.as_slice(), b"{\"foo\":1}");
17
+ /// assert_eq!(writer.finish()?.as_slice(), b"{\"foo\":1}");
18
+ /// # std::io::Result::Ok(())
19
+ /// ```
20
+ pub struct ToWriteJsonWriter < W : Write > {
21
+ write : W ,
22
+ writer : LowLevelJsonWriter ,
23
+ }
24
+
25
+ impl < W : Write > ToWriteJsonWriter < W > {
26
+ pub const fn new ( write : W ) -> Self {
27
+ Self {
28
+ write,
29
+ writer : LowLevelJsonWriter :: new ( ) ,
30
+ }
31
+ }
32
+
33
+ pub fn write_event ( & mut self , event : JsonEvent < ' _ > ) -> Result < ( ) > {
34
+ self . writer . write_event ( event, & mut self . write )
35
+ }
36
+
37
+ pub fn finish ( self ) -> Result < W > {
38
+ self . writer . validate_eof ( ) ?;
39
+ Ok ( self . write )
40
+ }
41
+ }
42
+
43
+ /// A JSON streaming writer writing to an [`AsyncWrite`] implementation.
44
+ ///
45
+ /// ```
46
+ /// use json_event_parser::{ToTokioAsyncWriteJsonWriter, JsonEvent};
17
47
///
48
+ /// # #[tokio::main(flavor = "current_thread")]
49
+ /// # async fn main() -> ::std::io::Result<()> {
50
+ /// let mut writer = ToTokioAsyncWriteJsonWriter::new(Vec::new());
51
+ /// writer.write_event(JsonEvent::StartObject).await?;
52
+ /// writer.write_event(JsonEvent::ObjectKey("foo".into())).await?;
53
+ /// writer.write_event(JsonEvent::Number("1".into())).await?;
54
+ /// writer.write_event(JsonEvent::EndObject).await?;
55
+ /// assert_eq!(writer.finish()?.as_slice(), b"{\"foo\":1}");
56
+ /// # Ok(())
57
+ /// # }
58
+ /// ```
59
+ #[ cfg( feature = "async-tokio" ) ]
60
+ pub struct ToTokioAsyncWriteJsonWriter < W : AsyncWrite + Unpin > {
61
+ write : W ,
62
+ writer : LowLevelJsonWriter ,
63
+ buffer : Vec < u8 > ,
64
+ }
65
+
66
+ #[ cfg( feature = "async-tokio" ) ]
67
+ impl < W : AsyncWrite + Unpin > ToTokioAsyncWriteJsonWriter < W > {
68
+ pub const fn new ( write : W ) -> Self {
69
+ Self {
70
+ write,
71
+ writer : LowLevelJsonWriter :: new ( ) ,
72
+ buffer : Vec :: new ( ) ,
73
+ }
74
+ }
75
+
76
+ pub async fn write_event ( & mut self , event : JsonEvent < ' _ > ) -> Result < ( ) > {
77
+ self . writer . write_event ( event, & mut self . buffer ) ?;
78
+ self . write . write_all ( & self . buffer ) . await ?;
79
+ self . buffer . clear ( ) ;
80
+ Ok ( ( ) )
81
+ }
82
+
83
+ pub fn finish ( self ) -> Result < W > {
84
+ self . writer . validate_eof ( ) ?;
85
+ Ok ( self . write )
86
+ }
87
+ }
88
+
89
+ /// A low-level JSON streaming writer writing to a [`Write`] implementation.
90
+ ///
91
+ /// YOu probably want to use [`ToWriteJsonWriter`] instead.
92
+ ///
93
+ /// ```
94
+ /// use json_event_parser::{JsonEvent, LowLevelJsonWriter};
95
+ ///
96
+ /// let mut writer = LowLevelJsonWriter::new();
97
+ /// let mut output = Vec::new();
98
+ /// writer.write_event(JsonEvent::StartObject, &mut output)?;
99
+ /// writer.write_event(JsonEvent::ObjectKey("foo".into()), &mut output)?;
100
+ /// writer.write_event(JsonEvent::Number("1".into()), &mut output)?;
101
+ /// writer.write_event(JsonEvent::EndObject, &mut output)?;
102
+ ///
103
+ /// assert_eq!(output.as_slice(), b"{\"foo\":1}");
18
104
/// # std::io::Result::Ok(())
19
105
/// ```
20
- pub struct JsonWriter < W : Write > {
21
- writer : W ,
106
+
107
+ #[ derive( Default ) ]
108
+ pub struct LowLevelJsonWriter {
22
109
state_stack : Vec < JsonState > ,
23
110
element_written : bool ,
24
111
}
25
112
26
- impl < W : Write > JsonWriter < W > {
27
- pub fn from_writer ( writer : W ) -> Self {
113
+ impl LowLevelJsonWriter {
114
+ pub const fn new ( ) -> Self {
28
115
Self {
29
- writer,
30
116
state_stack : Vec :: new ( ) ,
31
117
element_written : false ,
32
118
}
33
119
}
34
120
35
- pub fn into_inner ( self ) -> W {
36
- self . writer
37
- }
38
-
39
- pub fn inner ( & mut self ) -> & mut W {
40
- & mut self . writer
41
- }
42
-
43
- pub fn write_event ( & mut self , event : JsonEvent < ' _ > ) -> Result < ( ) > {
121
+ pub fn write_event ( & mut self , event : JsonEvent < ' _ > , mut write : impl Write ) -> Result < ( ) > {
44
122
match event {
45
123
JsonEvent :: String ( s) => {
46
- self . before_value ( ) ?;
47
- write_escaped_json_string ( & s, & mut self . writer )
124
+ self . before_value ( & mut write ) ?;
125
+ write_escaped_json_string ( & s, write )
48
126
}
49
127
JsonEvent :: Number ( number) => {
50
- self . before_value ( ) ?;
51
- self . writer . write_all ( number. as_bytes ( ) )
128
+ self . before_value ( & mut write ) ?;
129
+ write . write_all ( number. as_bytes ( ) )
52
130
}
53
131
JsonEvent :: Boolean ( b) => {
54
- self . before_value ( ) ?;
55
- self . writer . write_all ( if b { b"true" } else { b"false" } )
132
+ self . before_value ( & mut write ) ?;
133
+ write . write_all ( if b { b"true" } else { b"false" } )
56
134
}
57
135
JsonEvent :: Null => {
58
- self . before_value ( ) ?;
59
- self . writer . write_all ( b"null" )
136
+ self . before_value ( & mut write ) ?;
137
+ write . write_all ( b"null" )
60
138
}
61
139
JsonEvent :: StartArray => {
62
- self . before_value ( ) ?;
140
+ self . before_value ( & mut write ) ?;
63
141
self . state_stack . push ( JsonState :: OpenArray ) ;
64
- self . writer . write_all ( b"[" )
142
+ write . write_all ( b"[" )
65
143
}
66
144
JsonEvent :: EndArray => match self . state_stack . pop ( ) {
67
145
Some ( JsonState :: OpenArray ) | Some ( JsonState :: ContinuationArray ) => {
68
- self . writer . write_all ( b"]" )
146
+ write . write_all ( b"]" )
69
147
}
70
148
Some ( s) => {
71
149
self . state_stack . push ( s) ;
@@ -80,13 +158,13 @@ impl<W: Write> JsonWriter<W> {
80
158
) ) ,
81
159
} ,
82
160
JsonEvent :: StartObject => {
83
- self . before_value ( ) ?;
161
+ self . before_value ( & mut write ) ?;
84
162
self . state_stack . push ( JsonState :: OpenObject ) ;
85
- self . writer . write_all ( b"{" )
163
+ write . write_all ( b"{" )
86
164
}
87
165
JsonEvent :: EndObject => match self . state_stack . pop ( ) {
88
166
Some ( JsonState :: OpenObject ) | Some ( JsonState :: ContinuationObject ) => {
89
- self . writer . write_all ( b"}" )
167
+ write . write_all ( b"}" )
90
168
}
91
169
Some ( s) => {
92
170
self . state_stack . push ( s) ;
@@ -103,7 +181,7 @@ impl<W: Write> JsonWriter<W> {
103
181
JsonEvent :: ObjectKey ( key) => {
104
182
match self . state_stack . pop ( ) {
105
183
Some ( JsonState :: OpenObject ) => ( ) ,
106
- Some ( JsonState :: ContinuationObject ) => self . writer . write_all ( b"," ) ?,
184
+ Some ( JsonState :: ContinuationObject ) => write . write_all ( b"," ) ?,
107
185
_ => {
108
186
return Err ( Error :: new (
109
187
ErrorKind :: InvalidInput ,
@@ -113,8 +191,8 @@ impl<W: Write> JsonWriter<W> {
113
191
}
114
192
self . state_stack . push ( JsonState :: ContinuationObject ) ;
115
193
self . state_stack . push ( JsonState :: ObjectValue ) ;
116
- write_escaped_json_string ( & key, & mut self . writer ) ?;
117
- self . writer . write_all ( b":" )
194
+ write_escaped_json_string ( & key, & mut write ) ?;
195
+ write . write_all ( b":" )
118
196
}
119
197
JsonEvent :: Eof => Err ( Error :: new (
120
198
ErrorKind :: InvalidInput ,
@@ -123,15 +201,15 @@ impl<W: Write> JsonWriter<W> {
123
201
}
124
202
}
125
203
126
- fn before_value ( & mut self ) -> Result < ( ) > {
204
+ fn before_value ( & mut self , mut write : impl Write ) -> Result < ( ) > {
127
205
match self . state_stack . pop ( ) {
128
206
Some ( JsonState :: OpenArray ) => {
129
207
self . state_stack . push ( JsonState :: ContinuationArray ) ;
130
208
Ok ( ( ) )
131
209
}
132
210
Some ( JsonState :: ContinuationArray ) => {
133
211
self . state_stack . push ( JsonState :: ContinuationArray ) ;
134
- self . writer . write_all ( b"," ) ?;
212
+ write . write_all ( b"," ) ?;
135
213
Ok ( ( ) )
136
214
}
137
215
Some ( last_state @ JsonState :: OpenObject )
@@ -156,6 +234,22 @@ impl<W: Write> JsonWriter<W> {
156
234
}
157
235
}
158
236
}
237
+
238
+ fn validate_eof ( & self ) -> Result < ( ) > {
239
+ if !self . state_stack . is_empty ( ) {
240
+ return Err ( Error :: new (
241
+ ErrorKind :: InvalidInput ,
242
+ "The written JSON is not balanced: an object or an array has not been closed" ,
243
+ ) ) ;
244
+ }
245
+ if !self . element_written {
246
+ return Err ( Error :: new (
247
+ ErrorKind :: InvalidInput ,
248
+ "A JSON file can't be empty" ,
249
+ ) ) ;
250
+ }
251
+ Ok ( ( ) )
252
+ }
159
253
}
160
254
161
255
enum JsonState {
@@ -166,37 +260,37 @@ enum JsonState {
166
260
ObjectValue ,
167
261
}
168
262
169
- fn write_escaped_json_string ( s : & str , sink : & mut impl Write ) -> Result < ( ) > {
170
- sink . write_all ( b"\" " ) ?;
263
+ fn write_escaped_json_string ( s : & str , mut write : impl Write ) -> Result < ( ) > {
264
+ write . write_all ( b"\" " ) ?;
171
265
let mut buffer = [ b'\\' , b'u' , 0 , 0 , 0 , 0 ] ;
172
266
for c in s. chars ( ) {
173
267
match c {
174
- '\\' => sink . write_all ( b"\\ \\ " ) ,
175
- '"' => sink . write_all ( b"\\ \" " ) ,
268
+ '\\' => write . write_all ( b"\\ \\ " ) ,
269
+ '"' => write . write_all ( b"\\ \" " ) ,
176
270
c => {
177
271
if c < char:: from ( 32 ) {
178
272
match c {
179
- '\u{08}' => sink . write_all ( b"\\ b" ) ,
180
- '\u{0C}' => sink . write_all ( b"\\ f" ) ,
181
- '\n' => sink . write_all ( b"\\ n" ) ,
182
- '\r' => sink . write_all ( b"\\ r" ) ,
183
- '\t' => sink . write_all ( b"\\ t" ) ,
273
+ '\u{08}' => write . write_all ( b"\\ b" ) ,
274
+ '\u{0C}' => write . write_all ( b"\\ f" ) ,
275
+ '\n' => write . write_all ( b"\\ n" ) ,
276
+ '\r' => write . write_all ( b"\\ r" ) ,
277
+ '\t' => write . write_all ( b"\\ t" ) ,
184
278
c => {
185
279
let mut c = c as u8 ;
186
280
for i in ( 2 ..6 ) . rev ( ) {
187
281
let ch = c % 16 ;
188
282
buffer[ i] = if ch < 10 { b'0' + ch } else { b'A' + ch - 10 } ;
189
283
c /= 16 ;
190
284
}
191
- sink . write_all ( & buffer)
285
+ write . write_all ( & buffer)
192
286
}
193
287
}
194
288
} else {
195
- sink . write_all ( c. encode_utf8 ( & mut buffer[ 2 ..] ) . as_bytes ( ) )
289
+ write . write_all ( c. encode_utf8 ( & mut buffer[ 2 ..] ) . as_bytes ( ) )
196
290
}
197
291
}
198
292
} ?;
199
293
}
200
- sink . write_all ( b"\" " ) ?;
294
+ write . write_all ( b"\" " ) ?;
201
295
Ok ( ( ) )
202
296
}
0 commit comments