1mod val;
9
10use itoa::Buffer as ItoaBuffer;
11use nt_syntax::{STEP, push_indent};
12use serde::{
13 Serialize,
14 ser::{
15 self, Impossible, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
16 SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
17 },
18};
19pub use val::to_value;
20use zmij::Buffer as ZmijBuffer;
21
22use crate::{
23 dump::{is_inline_key, multiline, write_multiline_key, write_str_block},
24 error::{Error, Result},
25};
26
27pub fn to_string<T: Serialize + ?Sized>(value: &T) -> Result<String> {
29 let mut out = String::with_capacity(128);
30 value.serialize(StreamSer {
31 out: &mut out,
32 depth: 0,
33 ctx: Ctx::Root,
34 })?;
35 Ok(out)
36}
37
38#[derive(Clone, Copy, PartialEq, Eq)]
40enum Ctx {
41 Root,
43 AfterDash,
45 AfterColon,
47 BlockChild,
49}
50
51struct StreamSer<'a> {
52 out: &'a mut String,
53 depth: usize,
54 ctx: Ctx,
55}
56
57impl<'a> StreamSer<'a> {
58 #[inline]
60 fn emit_clean_scalar(self, s: &str) -> Result<()> {
61 match self.ctx {
62 Ctx::AfterColon | Ctx::AfterDash => {
63 if !s.is_empty() {
64 self.out.push(' ');
65 self.out.push_str(s);
66 }
67 self.out.push('\n');
68 }
69 Ctx::Root | Ctx::BlockChild => {
70 push_indent(self.out, self.depth);
71 if s.is_empty() {
72 self.out.push_str(">\n");
73 } else {
74 self.out.push_str("> ");
75 self.out.push_str(s);
76 self.out.push('\n');
77 }
78 }
79 }
80 Ok(())
81 }
82
83 fn emit_str(self, s: &str) -> Result<()> {
85 match self.ctx {
86 Ctx::AfterColon | Ctx::AfterDash => {
87 if s.is_empty() {
88 self.out.push('\n');
89 } else if !multiline(s) {
90 self.out.push(' ');
91 self.out.push_str(s);
92 self.out.push('\n');
93 } else {
94 self.out.push('\n');
95 write_str_block(self.out, self.depth + STEP, s);
96 }
97 }
98 Ctx::Root | Ctx::BlockChild => {
99 write_str_block(self.out, self.depth, s);
100 }
101 }
102 Ok(())
103 }
104
105 #[inline]
107 fn enter_container(&mut self) -> usize {
108 match self.ctx {
109 Ctx::AfterColon | Ctx::AfterDash => {
110 self.out.push('\n');
111 self.depth + STEP
112 }
113 Ctx::Root | Ctx::BlockChild => self.depth,
114 }
115 }
116}
117
118#[inline]
120fn write_dict_key(out: &mut String, depth: usize, raw_key: &str) -> (usize, Ctx) {
121 if is_inline_key(raw_key) {
122 push_indent(out, depth);
123 out.push_str(raw_key);
124 out.push(':');
125 (depth, Ctx::AfterColon)
126 } else {
127 write_multiline_key(out, depth, raw_key);
128 (depth + STEP, Ctx::BlockChild)
129 }
130}
131
132macro_rules! stream_int {
133 ($($method:ident => $t:ty),* $(,)?) => {
134 $(
135 #[inline]
136 fn $method(self, v: $t) -> Result<Self::Ok> {
137 let mut b = ItoaBuffer::new();
138 self.emit_clean_scalar(b.format(v))
139 }
140 )*
141 };
142}
143
144macro_rules! key_int {
145 ($($method:ident => $t:ty),* $(,)?) => {
146 $(
147 #[inline]
148 fn $method(self, v: $t) -> Result<Self::Ok> {
149 let mut b = ItoaBuffer::new();
150 self.emit(b.format(v))
151 }
152 )*
153 };
154}
155
156impl<'a> ser::Serializer for StreamSer<'a> {
157 type Ok = ();
158 type Error = Error;
159 type SerializeSeq = StreamSeq<'a>;
160 type SerializeTuple = StreamSeq<'a>;
161 type SerializeTupleStruct = StreamSeq<'a>;
162 type SerializeTupleVariant = StreamTupleVariant<'a>;
163 type SerializeMap = StreamMap<'a>;
164 type SerializeStruct = StreamMap<'a>;
165 type SerializeStructVariant = StreamStructVariant<'a>;
166
167 #[inline]
168 fn serialize_bool(self, v: bool) -> Result<()> {
169 self.emit_clean_scalar(if v { "true" } else { "false" })
170 }
171
172 stream_int! {
173 serialize_i8 => i8,
174 serialize_i16 => i16,
175 serialize_i32 => i32,
176 serialize_i64 => i64,
177 serialize_i128 => i128,
178 serialize_u8 => u8,
179 serialize_u16 => u16,
180 serialize_u32 => u32,
181 serialize_u64 => u64,
182 serialize_u128 => u128,
183 }
184
185 #[inline]
186 fn serialize_f32(self, v: f32) -> Result<()> {
187 let mut b = ZmijBuffer::new();
188 self.emit_clean_scalar(b.format(v))
189 }
190
191 #[inline]
192 fn serialize_f64(self, v: f64) -> Result<()> {
193 let mut b = ZmijBuffer::new();
194 self.emit_clean_scalar(b.format(v))
195 }
196
197 #[inline]
198 fn serialize_char(self, v: char) -> Result<()> {
199 let mut buf = [0u8; 4];
200 self.emit_str(v.encode_utf8(&mut buf))
201 }
202
203 #[inline]
204 fn serialize_str(self, v: &str) -> Result<()> {
205 self.emit_str(v)
206 }
207
208 fn serialize_bytes(self, _: &[u8]) -> Result<()> {
209 Err(Error::msg("NestedText does not support byte arrays"))
210 }
211
212 #[inline]
213 fn serialize_none(self) -> Result<()> {
214 self.emit_str("")
215 }
216
217 #[inline]
218 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<()> {
219 value.serialize(self)
220 }
221
222 #[inline]
223 fn serialize_unit(self) -> Result<()> {
224 self.emit_str("")
225 }
226
227 #[inline]
228 fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
229 self.emit_str("")
230 }
231
232 #[inline]
233 fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
234 self.emit_str(variant)
235 }
236
237 #[inline]
238 fn serialize_newtype_struct<T: Serialize + ?Sized>(
239 self,
240 _: &'static str,
241 value: &T,
242 ) -> Result<()> {
243 value.serialize(self)
244 }
245
246 fn serialize_newtype_variant<T: Serialize + ?Sized>(
247 mut self,
248 _: &'static str,
249 _: u32,
250 variant: &'static str,
251 value: &T,
252 ) -> Result<()> {
253 let d = self.enter_container();
254 let (vd, vctx) = write_dict_key(self.out, d, variant);
255 value.serialize(StreamSer {
256 out: self.out,
257 depth: vd,
258 ctx: vctx,
259 })
260 }
261
262 fn serialize_seq(mut self, len: Option<usize>) -> Result<StreamSeq<'a>> {
263 let d = self.enter_container();
264 if d == 0
265 && let Some(n) = len.filter(|&n| n > 0)
266 {
267 self.out.reserve(n.saturating_mul(16));
268 }
269 Ok(StreamSeq {
270 out: self.out,
271 depth: d,
272 count: 0,
273 })
274 }
275
276 fn serialize_tuple(self, len: usize) -> Result<StreamSeq<'a>> {
277 self.serialize_seq(Some(len))
278 }
279
280 fn serialize_tuple_struct(self, _: &'static str, len: usize) -> Result<StreamSeq<'a>> {
281 self.serialize_seq(Some(len))
282 }
283
284 fn serialize_tuple_variant(
285 mut self,
286 _: &'static str,
287 _: u32,
288 variant: &'static str,
289 _: usize,
290 ) -> Result<StreamTupleVariant<'a>> {
291 let d = self.enter_container();
292 let (vd, vctx) = write_dict_key(self.out, d, variant);
293 let seq_depth = match vctx {
294 Ctx::AfterColon => {
295 self.out.push('\n');
296 vd + STEP
297 }
298 _ => vd,
299 };
300 Ok(StreamTupleVariant {
301 seq: StreamSeq {
302 out: self.out,
303 depth: seq_depth,
304 count: 0,
305 },
306 })
307 }
308
309 fn serialize_map(mut self, len: Option<usize>) -> Result<StreamMap<'a>> {
310 let d = self.enter_container();
311 if d == 0
312 && let Some(n) = len.filter(|&n| n > 0)
313 {
314 self.out.reserve(n.saturating_mul(64));
315 }
316 Ok(StreamMap {
317 out: self.out,
318 depth: d,
319 count: 0,
320 val_target: None,
321 })
322 }
323
324 fn serialize_struct(self, _: &'static str, len: usize) -> Result<StreamMap<'a>> {
325 self.serialize_map(Some(len))
326 }
327
328 fn serialize_struct_variant(
329 mut self,
330 _: &'static str,
331 _: u32,
332 variant: &'static str,
333 _: usize,
334 ) -> Result<StreamStructVariant<'a>> {
335 let d = self.enter_container();
336 let (vd, vctx) = write_dict_key(self.out, d, variant);
337 let map_depth = match vctx {
338 Ctx::AfterColon => {
339 self.out.push('\n');
340 vd + STEP
341 }
342 _ => vd,
343 };
344 Ok(StreamStructVariant {
345 map: StreamMap {
346 out: self.out,
347 depth: map_depth,
348 count: 0,
349 val_target: None,
350 },
351 })
352 }
353}
354
355pub struct StreamSeq<'a> {
356 out: &'a mut String,
357 depth: usize,
358 count: usize,
359}
360
361impl SerializeSeq for StreamSeq<'_> {
362 type Ok = ();
363 type Error = Error;
364
365 #[inline]
366 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
367 self.count += 1;
368 push_indent(self.out, self.depth);
369 self.out.push('-');
370 value.serialize(StreamSer {
371 out: self.out,
372 depth: self.depth,
373 ctx: Ctx::AfterDash,
374 })
375 }
376
377 #[inline]
378 fn end(self) -> Result<()> {
379 if self.count == 0 {
380 push_indent(self.out, self.depth);
381 self.out.push_str("[]\n");
382 }
383 Ok(())
384 }
385}
386
387impl SerializeTuple for StreamSeq<'_> {
388 type Ok = ();
389 type Error = Error;
390
391 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
392 SerializeSeq::serialize_element(self, value)
393 }
394
395 fn end(self) -> Result<()> {
396 SerializeSeq::end(self)
397 }
398}
399
400impl SerializeTupleStruct for StreamSeq<'_> {
401 type Ok = ();
402 type Error = Error;
403
404 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
405 SerializeSeq::serialize_element(self, value)
406 }
407
408 fn end(self) -> Result<()> {
409 SerializeSeq::end(self)
410 }
411}
412
413pub struct StreamTupleVariant<'a> {
414 seq: StreamSeq<'a>,
415}
416
417impl SerializeTupleVariant for StreamTupleVariant<'_> {
418 type Ok = ();
419 type Error = Error;
420
421 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
422 SerializeSeq::serialize_element(&mut self.seq, value)
423 }
424
425 fn end(self) -> Result<()> {
426 SerializeSeq::end(self.seq)
427 }
428}
429
430pub struct StreamMap<'a> {
431 out: &'a mut String,
432 depth: usize,
433 count: usize,
434 val_target: Option<(usize, Ctx)>,
435}
436
437impl SerializeMap for StreamMap<'_> {
438 type Ok = ();
439 type Error = Error;
440
441 #[inline]
442 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<()> {
443 self.count += 1;
444 let target = key.serialize(KeyWriter {
445 out: self.out,
446 depth: self.depth,
447 })?;
448 self.val_target = Some(target);
449 Ok(())
450 }
451
452 #[inline]
453 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
454 let (vd, vctx) = self
455 .val_target
456 .take()
457 .ok_or_else(|| Error::msg("missing dictionary key"))?;
458 value.serialize(StreamSer {
459 out: self.out,
460 depth: vd,
461 ctx: vctx,
462 })
463 }
464
465 #[inline]
466 fn end(self) -> Result<()> {
467 if self.count == 0 {
468 push_indent(self.out, self.depth);
469 self.out.push_str("{}\n");
470 }
471 Ok(())
472 }
473}
474
475impl SerializeStruct for StreamMap<'_> {
476 type Ok = ();
477 type Error = Error;
478
479 #[inline]
480 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> {
481 self.count += 1;
482 let (vd, vctx) = write_dict_key(self.out, self.depth, key);
483 value.serialize(StreamSer {
484 out: self.out,
485 depth: vd,
486 ctx: vctx,
487 })
488 }
489
490 #[inline]
491 fn end(self) -> Result<()> {
492 SerializeMap::end(self)
493 }
494}
495
496pub struct StreamStructVariant<'a> {
497 map: StreamMap<'a>,
498}
499
500impl SerializeStructVariant for StreamStructVariant<'_> {
501 type Ok = ();
502 type Error = Error;
503
504 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> {
505 SerializeStruct::serialize_field(&mut self.map, key, value)
506 }
507
508 fn end(self) -> Result<()> {
509 SerializeStruct::end(self.map)
510 }
511}
512
513struct KeyWriter<'a> {
515 out: &'a mut String,
516 depth: usize,
517}
518
519impl KeyWriter<'_> {
520 #[inline]
521 fn emit(self, s: &str) -> Result<(usize, Ctx)> {
522 Ok(write_dict_key(self.out, self.depth, s))
523 }
524}
525
526impl ser::Serializer for KeyWriter<'_> {
527 type Ok = (usize, Ctx);
528 type Error = Error;
529 type SerializeSeq = Impossible<(usize, Ctx), Error>;
530 type SerializeTuple = Impossible<(usize, Ctx), Error>;
531 type SerializeTupleStruct = Impossible<(usize, Ctx), Error>;
532 type SerializeTupleVariant = Impossible<(usize, Ctx), Error>;
533 type SerializeMap = Impossible<(usize, Ctx), Error>;
534 type SerializeStruct = Impossible<(usize, Ctx), Error>;
535 type SerializeStructVariant = Impossible<(usize, Ctx), Error>;
536
537 fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
538 self.emit(if v { "true" } else { "false" })
539 }
540
541 key_int! {
542 serialize_i8 => i8,
543 serialize_i16 => i16,
544 serialize_i32 => i32,
545 serialize_i64 => i64,
546 serialize_i128 => i128,
547 serialize_u8 => u8,
548 serialize_u16 => u16,
549 serialize_u32 => u32,
550 serialize_u64 => u64,
551 serialize_u128 => u128,
552 }
553
554 fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
555 let mut b = ZmijBuffer::new();
556 self.emit(b.format(v))
557 }
558
559 fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
560 let mut b = ZmijBuffer::new();
561 self.emit(b.format(v))
562 }
563
564 fn serialize_char(self, v: char) -> Result<Self::Ok> {
565 let mut buf = [0u8; 4];
566 self.emit(v.encode_utf8(&mut buf))
567 }
568
569 #[inline]
570 fn serialize_str(self, v: &str) -> Result<Self::Ok> {
571 self.emit(v)
572 }
573
574 fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok> {
575 Err(Error::msg("NestedText dictionary keys must be strings"))
576 }
577
578 fn serialize_none(self) -> Result<Self::Ok> {
579 self.emit("")
580 }
581
582 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Self::Ok> {
583 value.serialize(self)
584 }
585
586 fn serialize_unit(self) -> Result<Self::Ok> {
587 self.emit("")
588 }
589
590 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok> {
591 self.emit("")
592 }
593
594 fn serialize_unit_variant(self, _: &'static str, _: u32, v: &'static str) -> Result<Self::Ok> {
595 self.emit(v)
596 }
597
598 fn serialize_newtype_struct<T: Serialize + ?Sized>(
599 self,
600 _: &'static str,
601 value: &T,
602 ) -> Result<Self::Ok> {
603 value.serialize(self)
604 }
605
606 fn serialize_newtype_variant<T: Serialize + ?Sized>(
607 self,
608 _: &'static str,
609 _: u32,
610 _: &'static str,
611 _: &T,
612 ) -> Result<Self::Ok> {
613 Err(Error::msg("NestedText dictionary keys must be strings"))
614 }
615
616 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
617 Err(Error::msg("NestedText dictionary keys must be strings"))
618 }
619
620 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
621 Err(Error::msg("NestedText dictionary keys must be strings"))
622 }
623
624 fn serialize_tuple_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeTupleStruct> {
625 Err(Error::msg("NestedText dictionary keys must be strings"))
626 }
627
628 fn serialize_tuple_variant(
629 self,
630 _: &'static str,
631 _: u32,
632 _: &'static str,
633 _: usize,
634 ) -> Result<Self::SerializeTupleVariant> {
635 Err(Error::msg("NestedText dictionary keys must be strings"))
636 }
637
638 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
639 Err(Error::msg("NestedText dictionary keys must be strings"))
640 }
641
642 fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
643 Err(Error::msg("NestedText dictionary keys must be strings"))
644 }
645
646 fn serialize_struct_variant(
647 self,
648 _: &'static str,
649 _: u32,
650 _: &'static str,
651 _: usize,
652 ) -> Result<Self::SerializeStructVariant> {
653 Err(Error::msg("NestedText dictionary keys must be strings"))
654 }
655}