1use std::borrow::Cow;
2
3use deser_core::ext::Number;
4use deser_core::ser::SerializeRef;
5use deser_core::ser::{self, EventSink, SerializeDriver};
6use deser_core::{Atom, BytesFormat, Error, ErrorKind, Event, Serialize, State};
7
8use crate::Nesting;
9use crate::encoding::encode;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
26#[non_exhaustive]
27pub enum ArrayFormat {
28 #[default]
33 Repeat,
34 Brackets,
38 Indices,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct SerializerConfig {
61 arrays: ArrayFormat,
62 nesting: Nesting,
63 space_as_plus: bool,
64 context: deser_core::Context,
65}
66
67impl Default for SerializerConfig {
68 fn default() -> SerializerConfig {
69 SerializerConfig::new()
70 }
71}
72
73impl SerializerConfig {
74 pub const fn new() -> SerializerConfig {
76 SerializerConfig {
77 arrays: ArrayFormat::Repeat,
78 nesting: Nesting::Brackets,
79 space_as_plus: true,
80 context: deser_core::Context::new(),
81 }
82 }
83
84 pub const fn builder() -> SerializerConfigBuilder {
86 SerializerConfigBuilder::new()
87 }
88
89 pub const fn into_builder(self) -> SerializerConfigBuilder {
91 SerializerConfigBuilder { value: self }
92 }
93
94 pub fn set_context(&mut self, context: deser_core::Context) {
102 self.context = context;
103 }
104
105 pub fn context(&self) -> &deser_core::Context {
107 &self.context
108 }
109
110 #[inline]
112 fn apply_context(&self, driver: &mut SerializeDriver<'_>) {
113 if !self.context.is_empty() {
114 driver.set_default_context(self.context.clone());
115 }
116 }
117
118 pub const fn set_arrays(&mut self, format: ArrayFormat) {
122 self.arrays = format;
123 }
124
125 pub const fn set_nesting(&mut self, nesting: Nesting) {
131 self.nesting = nesting;
132 }
133
134 pub const fn set_space_as_plus(&mut self, yes: bool) {
136 self.space_as_plus = yes;
137 }
138
139 pub fn to_string<T: Serialize + ?Sized>(&self, value: &T) -> Result<String, Error> {
141 self.to_string_ref(SerializeRef::new(&value))
142 }
143
144 pub fn to_string_with<F, T: Serialize + ?Sized>(
149 &self,
150 value: &T,
151 setup: F,
152 ) -> Result<String, Error>
153 where
154 F: FnOnce(&mut SerializeDriver<'_>),
155 {
156 let mut driver = SerializeDriver::new(&value);
157 setup(&mut driver);
158 self.apply_context(&mut driver);
159 let mut out = String::new();
160 self.serialize_driver(&mut driver, &mut out)?;
161 Ok(out)
162 }
163
164 fn to_string_ref(&self, value: SerializeRef<'_>) -> Result<String, Error> {
170 let mut driver = SerializeDriver::from_ref(value);
171 self.apply_context(&mut driver);
172 let mut out = String::new();
173 self.serialize_driver(&mut driver, &mut out)?;
174 Ok(out)
175 }
176
177 pub(crate) fn value_writer(&self, out: String, bytes: BytesFormat) -> Writer {
179 Writer {
180 config: self.clone(),
181 bytes,
182 separate: false,
183 out,
184 key: String::new(),
185 stack: Vec::new(),
186 limit: usize::MAX,
187 }
188 }
189
190 pub(crate) fn serialize_part(
199 &self,
200 value: &mut Option<Box<Writer>>,
201 driver: &mut SerializeDriver<'_>,
202 out: &mut String,
203 separate: &mut bool,
204 limit: usize,
205 ) -> Result<bool, Error> {
206 if value.is_none() && limit == usize::MAX {
209 return self.serialize_whole(driver, out, separate).map(|()| true);
210 }
211 let len = out.len();
212 let mut writer = value.take().unwrap_or_else(|| {
213 let mut writer = self.value_writer(String::new(), BytesFormat::of(driver.state()));
214 writer.separate = *separate;
215 Box::new(writer)
216 });
217 let adopt = out.is_empty();
220 if adopt {
221 writer.out = std::mem::take(out);
222 }
223 writer.limit = limit;
225 let rv = driver.drive_until(&mut *writer);
226 let output = std::mem::take(&mut writer.out);
227 let done = match rv {
228 Ok(done) => done,
229 Err(err) => {
230 if adopt {
231 *out = output;
232 }
233 out.truncate(len);
234 return Err(err);
235 }
236 };
237 if adopt {
238 *out = output;
239 } else {
240 out.push_str(&output);
241 }
242 if done {
243 *separate = writer.separate;
244 } else {
245 *value = Some(writer);
246 }
247 Ok(done)
248 }
249
250 fn serialize_whole(
257 &self,
258 driver: &mut SerializeDriver<'_>,
259 out: &mut String,
260 separate: &mut bool,
261 ) -> Result<(), Error> {
262 let len = out.len();
263 let mut writer = self.value_writer(std::mem::take(out), BytesFormat::of(driver.state()));
264 writer.separate = *separate;
265 let rv = driver.drive(|event, state| writer.event(event, state));
266 *out = writer.out;
267 if let Err(err) = rv {
268 out.truncate(len);
269 return Err(err);
270 }
271 *separate = writer.separate;
272 Ok(())
273 }
274
275 pub(crate) fn serialize_driver(
277 &self,
278 driver: &mut SerializeDriver<'_>,
279 out: &mut String,
280 ) -> Result<(), Error> {
281 self.serialize_whole(driver, out, &mut false)
282 }
283}
284
285#[derive(Debug, Clone)]
289#[must_use]
290pub struct SerializerConfigBuilder {
291 value: SerializerConfig,
292}
293
294impl SerializerConfigBuilder {
295 pub const fn new() -> SerializerConfigBuilder {
297 SerializerConfigBuilder {
298 value: SerializerConfig::new(),
299 }
300 }
301
302 pub const fn arrays(mut self, format: ArrayFormat) -> SerializerConfigBuilder {
306 self.value.set_arrays(format);
307 self
308 }
309
310 pub const fn nesting(mut self, nesting: Nesting) -> SerializerConfigBuilder {
314 self.value.set_nesting(nesting);
315 self
316 }
317
318 pub const fn space_as_plus(mut self, yes: bool) -> SerializerConfigBuilder {
322 self.value.set_space_as_plus(yes);
323 self
324 }
325
326 pub fn context(mut self, context: deser_core::Context) -> SerializerConfigBuilder {
330 self.value.set_context(context);
331 self
332 }
333
334 pub const fn build(self) -> SerializerConfig {
336 let value = unsafe { core::ptr::read(&self.value) };
340 core::mem::forget(self);
341 value
342 }
343}
344
345impl Default for SerializerConfigBuilder {
346 fn default() -> SerializerConfigBuilder {
347 SerializerConfigBuilder::new()
348 }
349}
350
351pub struct Serializer {
372 config: SerializerConfig,
373 out: String,
374 separate: bool,
376 value: Option<Box<Writer>>,
378 in_progress: bool,
380}
381
382impl Default for Serializer {
383 fn default() -> Serializer {
384 Serializer::new()
385 }
386}
387
388impl Clone for Serializer {
389 fn clone(&self) -> Serializer {
395 Serializer {
396 config: self.config.clone(),
397 out: self.out.clone(),
398 separate: self.separate,
399 value: None,
400 in_progress: self.in_progress,
401 }
402 }
403}
404
405impl std::fmt::Debug for Serializer {
406 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
407 f.debug_struct("Serializer")
408 .field("config", &self.config)
409 .field("output", &self.out)
410 .field("in_progress", &self.in_progress)
411 .finish()
412 }
413}
414
415impl Serializer {
416 pub fn new() -> Serializer {
418 Serializer::with_config(SerializerConfig::new())
419 }
420
421 pub fn with_config(config: SerializerConfig) -> Serializer {
423 Serializer {
424 config,
425 out: String::new(),
426 separate: false,
427 value: None,
428 in_progress: false,
429 }
430 }
431
432 pub fn config(&self) -> &SerializerConfig {
434 &self.config
435 }
436
437 pub fn serialize<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
441 ser::Serializer::serialize(self, value)
442 }
443
444 pub fn serialize_with<F, T: Serialize + ?Sized>(
449 &mut self,
450 value: &T,
451 setup: F,
452 ) -> Result<(), Error>
453 where
454 F: FnOnce(&mut SerializeDriver<'_>),
455 {
456 ser::Serializer::serialize_with(self, value, setup)
457 }
458
459 pub fn as_str(&self) -> &str {
461 &self.out
462 }
463
464 pub fn finish(self) -> String {
466 self.out
467 }
468}
469
470impl ser::Serializer for Serializer {
471 fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
472 if self.in_progress {
474 return Err(Error::in_progress());
475 }
476 ser::StreamSerializer::drive_partial(self, driver, usize::MAX).map(|_| ())
477 }
478}
479
480impl ser::StreamSerializer for Serializer {
481 fn output(&self) -> &[u8] {
482 self.out.as_bytes()
483 }
484
485 fn clear_output(&mut self) {
486 self.out.clear();
487 }
488
489 fn supports_partial(&self) -> bool {
490 true
491 }
492
493 fn drive_partial(
494 &mut self,
495 driver: &mut SerializeDriver<'_>,
496 limit: usize,
497 ) -> Result<bool, Error> {
498 if !self.config.context.is_empty() {
499 driver.set_default_context(self.config.context.clone());
500 }
501 if self.value.is_none() && self.in_progress {
502 return Err(Error::in_progress());
503 }
504 if !self.config.serialize_part(
507 &mut self.value,
508 driver,
509 &mut self.out,
510 &mut self.separate,
511 limit,
512 )? {
513 self.in_progress = true;
514 return Ok(false);
515 }
516 self.in_progress = false;
517 Ok(true)
518 }
519
520 fn in_progress(&self) -> bool {
521 self.in_progress
522 }
523}
524
525#[cfg(feature = "io")]
526impl SerializerConfig {
527 pub fn writer<W: std::io::Write>(&self, writer: W) -> deser_core::io::Writer<W, Serializer> {
533 deser_core::io::Writer::new(writer, Serializer::with_config(self.clone()))
534 }
535
536 pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
540 &self,
541 writer: W,
542 value: &T,
543 ) -> Result<(), Error> {
544 self.writer(writer).write(value)
545 }
546}
547
548#[cfg(feature = "io")]
559pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
560 writer: W,
561 value: &T,
562) -> Result<(), Error> {
563 SerializerConfig::new().to_writer(writer, value)
564}
565
566pub fn to_string<T: Serialize + ?Sized>(value: &T) -> Result<String, Error> {
592 SerializerConfig::new().to_string(value)
593}
594
595enum Frame {
597 Map { prefix: usize },
599 Seq { prefix: usize, index: usize },
602 Pairs,
604 Pair(u8),
607}
608
609pub(crate) struct Writer {
611 config: SerializerConfig,
612 bytes: BytesFormat,
614 separate: bool,
616 out: String,
617 key: String,
619 stack: Vec<Frame>,
620 limit: usize,
622}
623
624impl EventSink for Writer {
625 fn event(
626 &mut self,
627 event: Event<'_>,
628 _value: SerializeRef<'_>,
629 state: &mut State,
630 ) -> Result<(), Error> {
631 Writer::event(self, event, state)
632 }
633
634 fn pause(&mut self) -> bool {
635 self.out.len() >= self.limit
637 }
638}
639
640impl Writer {
641 fn event(&mut self, event: Event, state: &State) -> Result<(), Error> {
642 match (self.stack.last_mut(), event) {
643 (None, Event::MapStart(_)) => self.stack.push(Frame::Map { prefix: 0 }),
644 (None, Event::SeqStart(_)) => self.stack.push(Frame::Pairs),
645 (None, Event::Atom(Atom::Null)) => {}
646 (None, _) => {
647 return Err(Error::new(
648 ErrorKind::UnsupportedType,
649 "query strings hold maps or sequences of key-value pairs",
650 ));
651 }
652
653 (Some(Frame::Map { .. }), Event::MapEnd) => {
654 self.stack.pop();
655 }
656 (Some(&mut Frame::Map { prefix }), event) => {
657 if state.is_map_key() {
658 let key = match event {
659 Event::Atom(ref atom) => self.key_text(atom)?,
660 _ => return Err(unsupported_key()),
661 };
662 self.key.truncate(prefix);
663 if prefix > 0 {
664 if key.is_empty() {
666 return Err(Error::new(
667 ErrorKind::UnsupportedType,
668 "nested keys of query strings must not be empty",
669 ));
670 }
671 self.push_nested(&key);
672 } else {
673 self.key.push_str(&key);
674 }
675 } else {
676 self.value(event, false)?;
677 }
678 }
679
680 (Some(Frame::Seq { .. }), Event::SeqEnd) => {
681 self.stack.pop();
682 }
683 (
684 Some(&mut Frame::Seq {
685 prefix,
686 ref mut index,
687 }),
688 event,
689 ) => {
690 let element = *index;
691 *index += 1;
692 self.key.truncate(prefix);
693 match self.config.arrays {
694 ArrayFormat::Repeat => {}
695 ArrayFormat::Brackets => self.key.push_str("[]"),
696 ArrayFormat::Indices => self.push_nested(&element.to_string()),
697 }
698 if self.config.arrays != ArrayFormat::Indices
699 && matches!(event, Event::MapStart(_) | Event::SeqStart(_))
700 {
701 return Err(Error::new(
702 ErrorKind::UnsupportedType,
703 "sequences of maps or sequences require ArrayFormat::Indices",
704 ));
705 }
706 self.value(event, true)?;
707 }
708
709 (Some(Frame::Pairs), Event::SeqStart(_)) => self.stack.push(Frame::Pair(0)),
710 (Some(Frame::Pairs), Event::SeqEnd) => {
711 self.stack.pop();
712 }
713 (Some(Frame::Pair(state @ 0)), Event::Atom(ref atom)) => {
714 *state = 1;
715 let key = self.key_text(atom)?;
716 self.key.clear();
717 self.key.push_str(&key);
718 }
719 (Some(Frame::Pair(1)), Event::SeqEnd) => {
720 return Err(Error::new(
721 ErrorKind::UnsupportedType,
722 "key-value pairs need a value",
723 ));
724 }
725 (Some(Frame::Pair(state @ 1)), event) => {
726 *state = 2;
727 self.value(event, false)?;
728 }
729 (Some(Frame::Pair(2)), Event::SeqEnd) => {
730 self.stack.pop();
731 }
732 (Some(Frame::Pairs | Frame::Pair(_)), _) => {
733 return Err(Error::new(
734 ErrorKind::UnsupportedType,
735 "sequences at the top level must hold key-value pairs",
736 ));
737 }
738 }
739 Ok(())
740 }
741
742 fn value(&mut self, event: Event, in_seq: bool) -> Result<(), Error> {
744 match event {
745 Event::Atom(atom) => {
746 let value = match self.value_text(&atom)? {
747 Some(value) => value,
748 None if in_seq => Cow::Borrowed(""),
751 None => return Ok(()),
752 };
753 self.check_key()?;
754 if self.separate {
755 self.out.push('&');
756 }
757 self.separate = true;
758 encode(
759 self.key.as_bytes(),
760 self.config.space_as_plus,
761 &mut self.out,
762 );
763 self.out.push('=');
764 encode(value.as_bytes(), self.config.space_as_plus, &mut self.out);
765 }
766 Event::MapStart(_) | Event::SeqStart(_)
769 if self.key.is_empty()
770 && (matches!(event, Event::MapStart(_))
771 || self.config.arrays != ArrayFormat::Repeat) =>
772 {
773 return Err(Error::new(
774 ErrorKind::UnsupportedType,
775 "maps and sequences in query strings need a key that is not empty",
776 ));
777 }
778 Event::MapStart(_) => {
779 if self.config.nesting == Nesting::Flat {
780 return Err(Error::new(
781 ErrorKind::UnsupportedType,
782 "nested maps are not supported with Nesting::Flat",
783 ));
784 }
785 self.stack.push(Frame::Map {
786 prefix: self.key.len(),
787 });
788 }
789 Event::SeqStart(_) => self.stack.push(Frame::Seq {
790 prefix: self.key.len(),
791 index: 0,
792 }),
793 Event::MapEnd | Event::SeqEnd => unreachable!("ends are handled by the frames"),
794 }
795 Ok(())
796 }
797
798 fn check_key(&self) -> Result<(), Error> {
805 if self.config.nesting == Nesting::Flat {
806 return Ok(());
807 }
808 let mut bounds = Vec::new();
810 for frame in &self.stack {
811 match *frame {
812 Frame::Map { prefix } | Frame::Seq { prefix, .. } => bounds.push(prefix),
813 Frame::Pairs | Frame::Pair(_) => bounds.push(0),
814 }
815 }
816 bounds.push(self.key.len());
817 bounds.dedup();
819
820 let mut segments = Vec::new();
821 let first = crate::de::split_key(&self.key, self.config.nesting, &mut segments);
822 let ok = first == bounds.get(1).copied().unwrap_or(self.key.len())
823 && segments.len() + 2 == bounds.len().max(2)
824 && segments
825 .iter()
826 .zip(bounds[1..].windows(2))
827 .all(|(segment, part)| {
828 let end = match self.config.nesting {
829 Nesting::Brackets => part[1] - 1,
830 _ => part[1],
831 };
832 match *segment {
833 crate::de::Segment::Name(start, end2)
834 | crate::de::Segment::Index(_, start, end2) => {
835 start == part[0] + 1 && end2 == end
836 }
837 crate::de::Segment::Push => &self.key[part[0]..part[1]] == "[]",
838 }
839 });
840 if ok {
841 Ok(())
842 } else {
843 Err(Error::new(
844 ErrorKind::UnsupportedType,
845 format!(
846 "the key {:?} would be split differently into nested keys",
847 self.key
848 ),
849 ))
850 }
851 }
852
853 fn push_nested(&mut self, key: &str) {
855 match self.config.nesting {
856 Nesting::Dots => {
857 self.key.push('.');
858 self.key.push_str(key);
859 }
860 Nesting::Brackets | Nesting::Flat => {
861 self.key.push('[');
862 self.key.push_str(key);
863 self.key.push(']');
864 }
865 }
866 }
867
868 fn key_text<'a>(&self, atom: &'a Atom<'_>) -> Result<Cow<'a, str>, Error> {
870 match atom {
871 Atom::Null | Atom::Bytes(_) => Err(unsupported_key()),
872 atom => self.value_text(atom)?.ok_or_else(unsupported_key),
873 }
874 }
875
876 fn value_text<'a>(&self, atom: &'a Atom<'_>) -> Result<Option<Cow<'a, str>>, Error> {
878 Ok(Some(match *atom {
879 Atom::Null => return Ok(None),
880 Atom::Implicit(ref value) => {
882 return Ok(self
883 .value_text(&value.value().to_atom())?
884 .map(|text| Cow::Owned(text.into_owned())));
885 }
886 Atom::Bool(value) => Cow::Borrowed(if value { "true" } else { "false" }),
887 Atom::Str(ref value) | Atom::Lexical(ref value) => Cow::Borrowed(&**value),
888 Atom::Char(value) => Cow::Owned(value.to_string()),
889 Atom::U64(value) => Cow::Owned(value.to_string()),
890 Atom::I64(value) => Cow::Owned(value.to_string()),
891 Atom::F32(value) => Cow::Owned(zmij::Buffer::new().format(value).into()),
892 Atom::F64(value) => Cow::Owned(zmij::Buffer::new().format(value).into()),
893 Atom::Bytes(ref bytes) => {
894 let format = bytes.fallback.copied().unwrap_or(self.bytes);
895 Cow::Owned(
896 format
897 .encode(bytes)
898 .or_else(|| BytesFormat::BASE64.encode(bytes))
899 .unwrap_or_default(),
900 )
901 }
902 Atom::Ext(ref ext) => {
903 if let Some(number) = ext.downcast_value_ref::<Number>() {
904 Cow::Owned(number.as_str().to_string())
906 } else if let Some(value) = ext.downcast_ref::<u128>() {
907 Cow::Owned(value.to_string())
908 } else if let Some(value) = ext.downcast_ref::<i128>() {
909 Cow::Owned(value.to_string())
910 } else {
911 match ext.fallback() {
912 Atom::Ext(_) => {
913 return Err(Error::new(
914 ErrorKind::UnsupportedType,
915 format!("query strings do not support {}", ext.name()),
916 ));
917 }
918 fallback => match self.value_text(&fallback)? {
919 Some(text) => Cow::Owned(text.into_owned()),
920 None => return Ok(None),
921 },
922 }
923 }
924 }
925 _ => {
926 return Err(Error::new(
927 ErrorKind::UnsupportedType,
928 format!("query strings do not support {}", atom.name()),
929 ));
930 }
931 }))
932 }
933}
934
935#[cold]
936fn unsupported_key() -> Error {
937 Error::new(
938 ErrorKind::UnsupportedType,
939 "keys of query strings must be strings, numbers or booleans",
940 )
941}