docspec_json/
struson_backend.rs1use std::io::Write;
4
5use struson::writer::{JsonStreamWriter, JsonWriter as _};
6
7use crate::JsonBackend;
8use docspec_core::{Error, Result};
9
10pub struct StrusonBackend<W: Write> {
15 writer: JsonStreamWriter<W>,
16}
17
18impl<W: Write> StrusonBackend<W> {
19 #[inline]
21 pub fn new(writer: W) -> Self {
22 Self {
23 writer: JsonStreamWriter::new(writer),
24 }
25 }
26}
27
28impl<W: Write> JsonBackend for StrusonBackend<W> {
29 type Output = W;
30
31 #[inline]
32 fn begin_array(&mut self) -> Result<()> {
33 self.writer.begin_array().map_err(Error::from)
34 }
35
36 #[inline]
37 fn begin_object(&mut self) -> Result<()> {
38 self.writer.begin_object().map_err(Error::from)
39 }
40
41 #[inline]
42 fn end_array(&mut self) -> Result<()> {
43 self.writer.end_array().map_err(Error::from)
44 }
45
46 #[inline]
47 fn end_object(&mut self) -> Result<()> {
48 self.writer.end_object().map_err(Error::from)
49 }
50
51 #[inline]
52 fn finish(self) -> Result<W> {
53 self.writer.finish_document().map_err(Error::from)
54 }
55
56 #[inline]
57 fn write_bool(&mut self, b: bool) -> Result<()> {
58 self.writer.bool_value(b).map_err(Error::from)
59 }
60
61 #[inline]
62 fn write_name(&mut self, name: &str) -> Result<()> {
63 self.writer.name(name).map_err(Error::from)
64 }
65
66 #[inline]
67 fn write_null(&mut self) -> Result<()> {
68 self.writer.null_value().map_err(Error::from)
69 }
70
71 #[inline]
72 fn write_number(&mut self, n: u32) -> Result<()> {
73 self.writer.number_value(n).map_err(Error::from)
74 }
75
76 #[inline]
77 fn write_string(&mut self, s: &str) -> Result<()> {
78 self.writer.string_value(s).map_err(Error::from)
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 struct ErrorWriter;
87
88 impl Write for ErrorWriter {
89 fn flush(&mut self) -> std::io::Result<()> {
90 Ok(())
91 }
92
93 fn write(&mut self, _: &[u8]) -> std::io::Result<usize> {
94 Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, "test"))
95 }
96 }
97
98 #[test]
99 fn struson_backend_error_propagates_as_io_err() {
100 let mut b = StrusonBackend::new(ErrorWriter);
101 let result = b.begin_object();
102 assert!(matches!(result, Err(Error::Io { .. })));
103 }
104
105 #[test]
106 fn struson_backend_error_writer_flush_succeeds() {
107 let mut w = ErrorWriter;
108 assert!(w.flush().is_ok());
109 }
110
111 #[test]
112 fn struson_backend_finish_returns_underlying_writer() {
113 let mut b = StrusonBackend::new(Vec::new());
114 assert!(b.begin_array().is_ok());
115 assert!(b.end_array().is_ok());
116 let result = b.finish();
117 assert!(result.is_ok());
118 let bytes = result.unwrap_or_default();
119 assert!(bytes == b"[]");
120 }
121
122 #[test]
123 fn struson_backend_writes_array_of_values() {
124 let mut b = StrusonBackend::new(Vec::new());
125 assert!(b.begin_array().is_ok());
126 assert!(b.write_number(1).is_ok());
127 assert!(b.write_bool(true).is_ok());
128 assert!(b.write_null().is_ok());
129 assert!(b.write_string("x").is_ok());
130 assert!(b.end_array().is_ok());
131 let result = b.finish();
132 assert!(result.is_ok());
133 let bytes = result.unwrap_or_default();
134 assert!(bytes == br#"[1,true,null,"x"]"#);
135 }
136
137 #[test]
138 fn struson_backend_writes_empty_object() {
139 let mut b = StrusonBackend::new(Vec::new());
140 assert!(b.begin_object().is_ok());
141 assert!(b.end_object().is_ok());
142 let result = b.finish();
143 assert!(result.is_ok());
144 let bytes = result.unwrap_or_default();
145 assert!(bytes == b"{}");
146 }
147
148 #[test]
149 fn struson_backend_writes_nested_structure() {
150 let mut b = StrusonBackend::new(Vec::new());
151 assert!(b.begin_object().is_ok());
152 assert!(b.write_name("a").is_ok());
153 assert!(b.begin_array().is_ok());
154 assert!(b.write_number(1).is_ok());
155 assert!(b.begin_object().is_ok());
156 assert!(b.write_name("b").is_ok());
157 assert!(b.write_bool(true).is_ok());
158 assert!(b.end_object().is_ok());
159 assert!(b.end_array().is_ok());
160 assert!(b.end_object().is_ok());
161 let result = b.finish();
162 assert!(result.is_ok());
163 let bytes = result.unwrap_or_default();
164 assert!(bytes == br#"{"a":[1,{"b":true}]}"#);
165 }
166
167 #[test]
168 fn struson_backend_writes_simple_key_value() {
169 let mut b = StrusonBackend::new(Vec::new());
170 assert!(b.begin_object().is_ok());
171 assert!(b.write_name("k").is_ok());
172 assert!(b.write_string("v").is_ok());
173 assert!(b.end_object().is_ok());
174 let result = b.finish();
175 assert!(result.is_ok());
176 let bytes = result.unwrap_or_default();
177 assert!(bytes == br#"{"k":"v"}"#);
178 }
179}