1use crate::error::*;
2use serde::Serialize;
3use std::io::Write;
4
5pub fn to_vec<T>(value: &T, config: TextConfig) -> Result<Vec<u8>>
6where
7 T: Serialize + ?Sized,
8{
9 let mut result = Vec::with_capacity(256);
10 value.serialize(&mut TextSerializer::new(&mut result, config))?;
11 Ok(result)
12}
13
14pub fn to_vec_compact<T>(value: &T) -> Result<Vec<u8>>
15where
16 T: Serialize + ?Sized,
17{
18 to_vec(value, TextConfig::default())
19}
20
21pub fn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>>
22where
23 T: Serialize + ?Sized,
24{
25 to_vec(
26 value,
27 TextConfig::default().with_style(TextConfigStyle::default_pretty()),
28 )
29}
30
31pub fn to_string<T>(value: &T, config: TextConfig) -> Result<String>
32where
33 T: Serialize + ?Sized,
34{
35 Ok(unsafe { String::from_utf8_unchecked(to_vec(value, config)?) })
36}
37
38pub fn to_string_compact<T>(value: &T) -> Result<String>
39where
40 T: Serialize + ?Sized,
41{
42 to_string(value, TextConfig::default())
43}
44
45pub fn to_string_pretty<T>(value: &T) -> Result<String>
46where
47 T: Serialize + ?Sized,
48{
49 to_string(
50 value,
51 TextConfig::default().with_style(TextConfigStyle::default_pretty()),
52 )
53}
54
55#[derive(Debug, Clone)]
56pub struct TextConfig {
57 pub style: TextConfigStyle,
58 pub numbers_with_type: bool,
59}
60
61impl Default for TextConfig {
62 fn default() -> Self {
63 Self {
64 style: TextConfigStyle::Default,
65 numbers_with_type: true,
66 }
67 }
68}
69
70impl TextConfig {
71 pub fn with_style(mut self, style: TextConfigStyle) -> Self {
72 self.style = style;
73 self
74 }
75
76 pub fn with_numbers_with_type(mut self, mode: bool) -> Self {
77 self.numbers_with_type = mode;
78 self
79 }
80}
81
82#[derive(Debug, Default, Clone)]
83pub enum TextConfigStyle {
84 #[default]
85 Default,
86 Pretty {
87 level: usize,
88 indent: Option<usize>,
89 },
90}
91
92impl TextConfigStyle {
93 pub fn pretty(indent: Option<usize>) -> Self {
94 Self::Pretty { indent, level: 0 }
95 }
96
97 pub fn default_pretty() -> Self {
98 Self::Pretty {
99 indent: Some(2),
100 level: 0,
101 }
102 }
103
104 pub fn is_pretty(&self) -> bool {
105 matches!(self, Self::Pretty { .. })
106 }
107}
108
109#[derive(Debug, Default, Clone)]
110pub struct TextSerializer<W>
111where
112 W: Write,
113{
114 stream: W,
115 config: TextConfig,
116}
117
118impl<W> TextSerializer<W>
119where
120 W: Write,
121{
122 pub fn new(stream: W, config: TextConfig) -> Self {
123 Self { stream, config }
124 }
125
126 pub fn into_inner(self) -> W {
127 self.stream
128 }
129
130 fn push_level(&mut self) {
131 if let TextConfigStyle::Pretty { level, .. } = &mut self.config.style {
132 *level += 1;
133 }
134 }
135
136 fn pop_level(&mut self) {
137 if let TextConfigStyle::Pretty { level, .. } = &mut self.config.style {
138 if *level > 0 {
139 *level -= 1;
140 }
141 }
142 }
143
144 fn map_result<T>(result: std::io::Result<T>) -> Result<T> {
145 result.map_err(|e| Error::Message(format!("{}", e)))
146 }
147
148 fn write_whitespace(&mut self) -> Result<()> {
149 if self.config.style.is_pretty() {
150 Self::map_result(write!(&mut self.stream, " "))
151 } else {
152 Ok(())
153 }
154 }
155
156 fn write_separator(&mut self) -> Result<()> {
157 if let TextConfigStyle::Pretty { indent, .. } = &self.config.style {
158 if indent.is_none() {
159 return self.write_raw(", ");
160 }
161 }
162 self.write_raw(",")
163 }
164
165 fn write_new_line_indent(&mut self) -> Result<()> {
166 #[allow(clippy::collapsible_match)]
167 if let TextConfigStyle::Pretty { level, indent, .. } = &mut self.config.style {
168 if let Some(indent) = *indent {
169 Self::map_result(write!(
170 &mut self.stream,
171 "\n{:indent$}",
172 "",
173 indent = (*level) * indent
174 ))?;
175 }
176 }
177 Ok(())
178 }
179
180 fn write_raw(&mut self, value: &str) -> Result<()> {
181 Self::map_result(write!(&mut self.stream, "{}", value))
182 }
183
184 fn write_from_string(&mut self, value: impl ToString, typename: &str) -> Result<()> {
185 Self::map_result(write!(
186 &mut self.stream,
187 "{}_{}",
188 value.to_string(),
189 typename
190 ))
191 }
192
193 fn write_str(&mut self, value: &str) -> Result<()> {
194 Self::map_result(write!(&mut self.stream, "{:?}", value))
195 }
196
197 fn write_bytes(&mut self, value: &[u8]) -> Result<()> {
198 Self::map_result(write!(&mut self.stream, "0x"))?;
199 for byte in value {
200 Self::map_result(write!(&mut self.stream, "{:02x}", byte))?;
201 }
202 Ok(())
203 }
204}
205
206macro_rules! impl_serialize_number {
207 ($name:ident, $type:ident) => {
208 fn $name(self, v: $type) -> Result<Self::Ok> {
209 self.write_from_string(v, stringify!($type))
210 }
211 };
212}
213
214impl<'a, W> serde::ser::Serializer for &'a mut TextSerializer<W>
215where
216 W: Write,
217{
218 type Ok = ();
219 type Error = Error;
220 type SerializeSeq = SeqSerializer<'a, W>;
221 type SerializeTuple = TupleSerializer<'a, W>;
222 type SerializeTupleStruct = TupleStructSerializer<'a, W>;
223 type SerializeTupleVariant = TupleVariantSerializer<'a, W>;
224 type SerializeMap = MapSerializer<'a, W>;
225 type SerializeStruct = StructSerializer<'a, W>;
226 type SerializeStructVariant = StructVariantSerializer<'a, W>;
227
228 fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
229 if v {
230 self.write_raw("true")
231 } else {
232 self.write_raw("false")
233 }
234 }
235
236 impl_serialize_number!(serialize_i8, i8);
237 impl_serialize_number!(serialize_i16, i16);
238 impl_serialize_number!(serialize_i32, i32);
239 impl_serialize_number!(serialize_i64, i64);
240 impl_serialize_number!(serialize_i128, i128);
241 impl_serialize_number!(serialize_u8, u8);
242 impl_serialize_number!(serialize_u16, u16);
243 impl_serialize_number!(serialize_u32, u32);
244 impl_serialize_number!(serialize_u64, u64);
245 impl_serialize_number!(serialize_u128, u128);
246 impl_serialize_number!(serialize_f32, f32);
247 impl_serialize_number!(serialize_f64, f64);
248
249 fn serialize_char(self, v: char) -> Result<Self::Ok> {
250 TextSerializer::<W>::map_result(write!(&mut self.stream, "'{}'", v))
251 }
252
253 fn serialize_str(self, v: &str) -> Result<Self::Ok> {
254 self.write_str(v)
255 }
256
257 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
258 self.write_bytes(v)
259 }
260
261 fn serialize_none(self) -> Result<Self::Ok> {
262 self.write_raw("?")
263 }
264
265 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
266 where
267 T: ?Sized + Serialize,
268 {
269 self.write_raw("?")?;
270 self.write_whitespace()?;
271 self.write_raw("=")?;
272 self.write_whitespace()?;
273 value.serialize(self)
274 }
275
276 fn serialize_unit(self) -> Result<Self::Ok> {
277 self.write_raw("!")
278 }
279
280 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok> {
281 self.write_raw("#!")
282 }
283
284 fn serialize_unit_variant(
285 self,
286 _: &'static str,
287 _: u32,
288 variant: &'static str,
289 ) -> Result<Self::Ok> {
290 self.write_raw("@")?;
291 self.write_raw(variant)?;
292 self.write_whitespace()?;
293 self.write_raw("!")
294 }
295
296 fn serialize_newtype_struct<T>(self, _: &'static str, value: &T) -> Result<Self::Ok>
297 where
298 T: ?Sized + Serialize,
299 {
300 self.write_raw("$")?;
301 self.write_whitespace()?;
302 self.write_raw("=")?;
303 self.write_whitespace()?;
304 value.serialize(self)
305 }
306
307 fn serialize_newtype_variant<T>(
308 self,
309 _: &'static str,
310 _: u32,
311 variant: &'static str,
312 value: &T,
313 ) -> Result<Self::Ok>
314 where
315 T: ?Sized + Serialize,
316 {
317 self.write_raw("@")?;
318 self.write_raw(variant)?;
319 self.write_whitespace()?;
320 self.write_raw("$")?;
321 self.write_whitespace()?;
322 self.write_raw("=")?;
323 self.write_whitespace()?;
324 value.serialize(self)
325 }
326
327 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
328 self.write_raw("[")?;
329 self.push_level();
330 Ok(SeqSerializer {
331 stream: self,
332 first: true,
333 })
334 }
335
336 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
337 self.write_raw("(")?;
338 self.push_level();
339 Ok(TupleSerializer {
340 stream: self,
341 first: true,
342 })
343 }
344
345 fn serialize_tuple_struct(
346 self,
347 _: &'static str,
348 _: usize,
349 ) -> Result<Self::SerializeTupleStruct> {
350 self.write_raw("#")?;
351 self.write_whitespace()?;
352 self.write_raw("(")?;
353 self.push_level();
354 Ok(TupleStructSerializer {
355 stream: self,
356 first: true,
357 })
358 }
359
360 fn serialize_tuple_variant(
361 self,
362 _: &'static str,
363 _: u32,
364 variant: &'static str,
365 _: usize,
366 ) -> Result<Self::SerializeTupleVariant> {
367 self.write_raw("@")?;
368 self.write_raw(variant)?;
369 self.write_whitespace()?;
370 self.write_raw("(")?;
371 self.push_level();
372 Ok(TupleVariantSerializer {
373 stream: self,
374 first: true,
375 })
376 }
377
378 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
379 self.write_raw("{")?;
380 self.push_level();
381 Ok(MapSerializer {
382 stream: self,
383 first: true,
384 })
385 }
386
387 fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
388 self.write_raw("#")?;
389 self.write_whitespace()?;
390 self.write_raw("{")?;
391 self.push_level();
392 Ok(StructSerializer {
393 stream: self,
394 first: true,
395 })
396 }
397
398 fn serialize_struct_variant(
399 self,
400 _: &'static str,
401 _: u32,
402 variant: &'static str,
403 _: usize,
404 ) -> Result<Self::SerializeStructVariant> {
405 self.write_raw("@")?;
406 self.write_raw(variant)?;
407 self.write_whitespace()?;
408 self.write_raw("#")?;
409 self.write_whitespace()?;
410 self.write_raw("{")?;
411 self.push_level();
412 Ok(StructVariantSerializer {
413 stream: self,
414 first: true,
415 })
416 }
417}
418
419pub struct SeqSerializer<'a, W>
420where
421 W: Write,
422{
423 stream: &'a mut TextSerializer<W>,
424 first: bool,
425}
426
427impl<W> serde::ser::SerializeSeq for SeqSerializer<'_, W>
428where
429 W: Write,
430{
431 type Ok = ();
432 type Error = Error;
433
434 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
435 where
436 T: ?Sized + Serialize,
437 {
438 if self.first {
439 self.first = false;
440 } else {
441 self.stream.write_separator()?;
442 }
443 self.stream.write_new_line_indent()?;
444 value.serialize(&mut *self.stream)
445 }
446
447 fn end(self) -> Result<Self::Ok> {
448 self.stream.pop_level();
449 self.stream.write_new_line_indent()?;
450 self.stream.write_raw("]")
451 }
452}
453
454pub struct TupleSerializer<'a, W>
455where
456 W: Write,
457{
458 stream: &'a mut TextSerializer<W>,
459 first: bool,
460}
461
462impl<W> serde::ser::SerializeTuple for TupleSerializer<'_, W>
463where
464 W: Write,
465{
466 type Ok = ();
467 type Error = Error;
468
469 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
470 where
471 T: ?Sized + Serialize,
472 {
473 if self.first {
474 self.first = false;
475 } else {
476 self.stream.write_separator()?;
477 }
478 self.stream.write_new_line_indent()?;
479 value.serialize(&mut *self.stream)
480 }
481
482 fn end(self) -> Result<Self::Ok> {
483 self.stream.pop_level();
484 self.stream.write_new_line_indent()?;
485 self.stream.write_raw(")")
486 }
487}
488
489pub struct TupleStructSerializer<'a, W>
490where
491 W: Write,
492{
493 stream: &'a mut TextSerializer<W>,
494 first: bool,
495}
496
497impl<W> serde::ser::SerializeTupleStruct for TupleStructSerializer<'_, W>
498where
499 W: Write,
500{
501 type Ok = ();
502 type Error = Error;
503
504 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
505 where
506 T: ?Sized + Serialize,
507 {
508 if self.first {
509 self.first = false;
510 } else {
511 self.stream.write_separator()?;
512 }
513 self.stream.write_new_line_indent()?;
514 value.serialize(&mut *self.stream)
515 }
516
517 fn end(self) -> Result<Self::Ok> {
518 self.stream.pop_level();
519 self.stream.write_new_line_indent()?;
520 self.stream.write_raw(")")
521 }
522}
523
524pub struct TupleVariantSerializer<'a, W>
525where
526 W: Write,
527{
528 stream: &'a mut TextSerializer<W>,
529 first: bool,
530}
531
532impl<W> serde::ser::SerializeTupleVariant for TupleVariantSerializer<'_, W>
533where
534 W: Write,
535{
536 type Ok = ();
537 type Error = Error;
538
539 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
540 where
541 T: ?Sized + Serialize,
542 {
543 if self.first {
544 self.first = false;
545 } else {
546 self.stream.write_separator()?;
547 }
548 self.stream.write_new_line_indent()?;
549 value.serialize(&mut *self.stream)
550 }
551
552 fn end(self) -> Result<Self::Ok> {
553 self.stream.pop_level();
554 self.stream.write_new_line_indent()?;
555 self.stream.write_raw(")")
556 }
557}
558
559pub struct MapSerializer<'a, W>
560where
561 W: Write,
562{
563 stream: &'a mut TextSerializer<W>,
564 first: bool,
565}
566
567impl<W> serde::ser::SerializeMap for MapSerializer<'_, W>
568where
569 W: Write,
570{
571 type Ok = ();
572 type Error = Error;
573
574 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
575 where
576 T: ?Sized + Serialize,
577 {
578 if self.first {
579 self.first = false;
580 } else {
581 self.stream.write_separator()?;
582 }
583 self.stream.write_new_line_indent()?;
584 key.serialize(&mut *self.stream)
585 }
586
587 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
588 where
589 T: ?Sized + Serialize,
590 {
591 self.stream.write_raw(":")?;
592 self.stream.write_whitespace()?;
593 value.serialize(&mut *self.stream)
594 }
595
596 fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
597 where
598 K: ?Sized + Serialize,
599 V: ?Sized + Serialize,
600 {
601 if self.first {
602 self.first = false;
603 } else {
604 self.stream.write_separator()?;
605 }
606 self.stream.write_new_line_indent()?;
607 key.serialize(&mut *self.stream)?;
608 self.stream.write_raw(":")?;
609 self.stream.write_whitespace()?;
610 value.serialize(&mut *self.stream)
611 }
612
613 fn end(self) -> Result<Self::Ok> {
614 self.stream.pop_level();
615 self.stream.write_new_line_indent()?;
616 self.stream.write_raw("}")
617 }
618}
619
620pub struct StructSerializer<'a, W>
621where
622 W: Write,
623{
624 stream: &'a mut TextSerializer<W>,
625 first: bool,
626}
627
628impl<W> serde::ser::SerializeStruct for StructSerializer<'_, W>
629where
630 W: Write,
631{
632 type Ok = ();
633 type Error = Error;
634
635 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
636 where
637 T: ?Sized + Serialize,
638 {
639 if self.first {
640 self.first = false;
641 } else {
642 self.stream.write_separator()?;
643 }
644 self.stream.write_new_line_indent()?;
645 self.stream.write_raw(key)?;
646 self.stream.write_raw(":")?;
647 self.stream.write_whitespace()?;
648 value.serialize(&mut *self.stream)
649 }
650
651 fn end(self) -> Result<()> {
652 self.stream.pop_level();
653 self.stream.write_new_line_indent()?;
654 self.stream.write_raw("}")
655 }
656}
657
658pub struct StructVariantSerializer<'a, W>
659where
660 W: Write,
661{
662 stream: &'a mut TextSerializer<W>,
663 first: bool,
664}
665
666impl<W> serde::ser::SerializeStructVariant for StructVariantSerializer<'_, W>
667where
668 W: Write,
669{
670 type Ok = ();
671 type Error = Error;
672
673 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
674 where
675 T: ?Sized + Serialize,
676 {
677 if self.first {
678 self.first = false;
679 } else {
680 self.stream.write_separator()?;
681 }
682 self.stream.write_new_line_indent()?;
683 self.stream.write_raw(key)?;
684 self.stream.write_raw(":")?;
685 self.stream.write_whitespace()?;
686 value.serialize(&mut *self.stream)
687 }
688
689 fn end(self) -> Result<()> {
690 self.stream.pop_level();
691 self.stream.write_new_line_indent()?;
692 self.stream.write_raw("}")
693 }
694}