1use std::io::{Cursor, Read, Write};
6
7pub use crate::Context;
8use struson::writer::JsonNumberError;
9pub use struson::{
10 json_path,
11 reader::{JsonReader, JsonStreamReader, ValueType},
12 writer::{JsonStreamWriter, JsonWriter},
13};
14
15use crate::{EncodingResult, Error, UaNullable};
16
17pub trait JsonEncodable: UaNullable {
19 #[allow(unused)]
20 fn encode(
22 &self,
23 stream: &mut JsonStreamWriter<&mut dyn Write>,
24 ctx: &crate::Context<'_>,
25 ) -> EncodingResult<()>;
26}
27
28impl From<struson::reader::ReaderError> for Error {
29 fn from(value: struson::reader::ReaderError) -> Self {
30 Self::decoding(value)
31 }
32}
33
34impl From<JsonNumberError> for Error {
35 fn from(value: JsonNumberError) -> Self {
36 Self::encoding(value)
37 }
38}
39
40impl From<struson::reader::TransferError> for Error {
41 fn from(value: struson::reader::TransferError) -> Self {
42 Self::decoding(value)
43 }
44}
45
46pub trait JsonDecodable: Sized {
48 #[allow(unused)]
49 fn decode(
51 stream: &mut JsonStreamReader<&mut dyn Read>,
52 ctx: &Context<'_>,
53 ) -> EncodingResult<Self>;
54}
55
56impl<T> JsonEncodable for Option<T>
57where
58 T: JsonEncodable,
59{
60 fn encode(
61 &self,
62 stream: &mut JsonStreamWriter<&mut dyn Write>,
63 ctx: &crate::Context<'_>,
64 ) -> EncodingResult<()> {
65 match self {
66 Some(s) => s.encode(stream, ctx),
67 None => Ok(stream.null_value()?),
68 }
69 }
70}
71
72impl<T> JsonDecodable for Option<T>
73where
74 T: JsonDecodable,
75{
76 fn decode(
77 stream: &mut JsonStreamReader<&mut dyn Read>,
78 ctx: &Context<'_>,
79 ) -> EncodingResult<Self> {
80 match stream.peek()? {
81 ValueType::Null => {
82 stream.next_null()?;
83 Ok(None)
84 }
85 _ => Ok(Some(T::decode(stream, ctx)?)),
86 }
87 }
88}
89
90impl<T> JsonEncodable for Vec<T>
91where
92 T: JsonEncodable,
93{
94 fn encode(
95 &self,
96 stream: &mut JsonStreamWriter<&mut dyn Write>,
97 ctx: &crate::Context<'_>,
98 ) -> EncodingResult<()> {
99 stream.begin_array()?;
100 for elem in self {
101 elem.encode(stream, ctx)?;
102 }
103 stream.end_array()?;
104 Ok(())
105 }
106}
107
108impl<T> JsonDecodable for Vec<T>
109where
110 T: JsonDecodable,
111{
112 fn decode(
113 stream: &mut JsonStreamReader<&mut dyn Read>,
114 ctx: &Context<'_>,
115 ) -> EncodingResult<Self> {
116 if stream.peek()? == ValueType::Null {
117 stream.next_null()?;
118 return Ok(Vec::new());
119 }
120
121 let mut res = Vec::new();
122 stream.begin_array()?;
123 while stream.has_next()? {
124 res.push(T::decode(stream, ctx)?);
125 }
126 stream.end_array()?;
127
128 Ok(res)
129 }
130}
131
132impl<T> JsonEncodable for Box<T>
133where
134 T: JsonEncodable,
135{
136 fn encode(
137 &self,
138 stream: &mut JsonStreamWriter<&mut dyn Write>,
139 ctx: &crate::Context<'_>,
140 ) -> EncodingResult<()> {
141 T::encode(self, stream, ctx)
142 }
143}
144
145impl<T> JsonDecodable for Box<T>
146where
147 T: JsonDecodable,
148{
149 fn decode(
150 stream: &mut JsonStreamReader<&mut dyn Read>,
151 ctx: &Context<'_>,
152 ) -> EncodingResult<Self> {
153 Ok(Box::new(T::decode(stream, ctx)?))
154 }
155}
156
157const VALUE_INFINITY: &str = "Infinity";
158const VALUE_NEG_INFINITY: &str = "-Infinity";
159const VALUE_NAN: &str = "NaN";
160
161macro_rules! json_enc_float {
162 ($t:ty) => {
163 impl JsonEncodable for $t {
164 fn encode(
165 &self,
166 stream: &mut JsonStreamWriter<&mut dyn Write>,
167 _ctx: &crate::Context<'_>,
168 ) -> EncodingResult<()> {
169 if self.is_infinite() {
170 if self.is_sign_positive() {
171 stream.string_value(VALUE_INFINITY)?;
172 } else {
173 stream.string_value(VALUE_NEG_INFINITY)?;
174 }
175 } else if self.is_nan() {
176 stream.string_value(VALUE_NAN)?;
177 } else {
178 stream.fp_number_value(*self)?;
179 }
180
181 Ok(())
182 }
183 }
184
185 impl JsonDecodable for $t {
186 fn decode(
187 stream: &mut JsonStreamReader<&mut dyn Read>,
188 _ctx: &Context<'_>,
189 ) -> EncodingResult<Self> {
190 if stream.peek()? == ValueType::String {
191 let v = stream.next_str()?;
192 match v {
193 VALUE_INFINITY => Ok(Self::INFINITY),
194 VALUE_NEG_INFINITY => Ok(Self::NEG_INFINITY),
195 VALUE_NAN => Ok(Self::NAN),
196 r => Ok(r.parse()?),
199 }
200 } else {
201 Ok(stream.next_number()??)
202 }
203 }
204 }
205 };
206}
207
208macro_rules! json_enc_number {
209 ($t:ty) => {
210 impl JsonEncodable for $t {
211 fn encode(
212 &self,
213 stream: &mut JsonStreamWriter<&mut dyn Write>,
214 _ctx: &crate::Context<'_>,
215 ) -> EncodingResult<()> {
216 stream.number_value(*self)?;
217 Ok(())
218 }
219 }
220
221 impl JsonDecodable for $t {
222 fn decode(
223 stream: &mut JsonStreamReader<&mut dyn Read>,
224 _ctx: &Context<'_>,
225 ) -> EncodingResult<Self> {
226 Ok(stream.next_number()??)
227 }
228 }
229 };
230}
231
232json_enc_number!(u8);
233json_enc_number!(u16);
234json_enc_number!(u32);
235json_enc_number!(u64);
236json_enc_number!(i8);
237json_enc_number!(i16);
238json_enc_number!(i32);
239json_enc_number!(i64);
240json_enc_float!(f32);
241json_enc_float!(f64);
242
243impl JsonEncodable for String {
244 fn encode(
245 &self,
246 stream: &mut JsonStreamWriter<&mut dyn Write>,
247 _ctx: &crate::Context<'_>,
248 ) -> EncodingResult<()> {
249 stream.string_value(self.as_str())?;
250 Ok(())
251 }
252}
253
254impl JsonDecodable for String {
255 fn decode(
256 stream: &mut JsonStreamReader<&mut dyn Read>,
257 _ctx: &Context<'_>,
258 ) -> EncodingResult<Self> {
259 Ok(stream.next_string()?)
260 }
261}
262
263impl JsonEncodable for bool {
264 fn encode(
265 &self,
266 stream: &mut JsonStreamWriter<&mut dyn Write>,
267 _ctx: &crate::Context<'_>,
268 ) -> EncodingResult<()> {
269 stream.bool_value(*self)?;
270 Ok(())
271 }
272}
273
274impl JsonDecodable for bool {
275 fn decode(
276 stream: &mut JsonStreamReader<&mut dyn Read>,
277 _ctx: &Context<'_>,
278 ) -> EncodingResult<Self> {
279 Ok(stream.next_bool()?)
280 }
281}
282
283pub fn consume_raw_value(
286 r: &mut JsonStreamReader<&mut dyn std::io::Read>,
287) -> EncodingResult<Vec<u8>> {
288 let mut res = Vec::new();
289 let cursor = Cursor::new(&mut res);
290 let mut writer = JsonStreamWriter::new(cursor);
291 r.transfer_to(&mut writer)?;
292 writer.finish_document()?;
293 Ok(res)
294}
295
296pub fn write_raw_value(
298 data: &[u8],
299 r: &mut JsonStreamWriter<&mut dyn std::io::Write>,
300) -> EncodingResult<()> {
301 let cursor = Cursor::new(data);
302 let mut reader = JsonStreamReader::new(cursor);
303 reader.transfer_to(r)?;
304 Ok(())
305}