1use alloc::borrow::Cow;
4use alloc::collections::{BTreeSet, VecDeque};
5use alloc::format;
6use alloc::string::String;
7use alloc::string::ToString;
8use alloc::vec::Vec;
9#[cfg(feature = "std")]
10use core::hash::{BuildHasher, Hash};
11use core::marker::PhantomData;
12#[cfg(feature = "std")]
13use std::collections::HashSet;
14
15use crate::State;
16use crate::Text;
17use crate::adapters::Same;
18use crate::de::{Deserialize, Sink, SinkHandle};
19use crate::error::{Error, ErrorKind};
20use crate::event::{Atom, ContainerShape};
21use crate::ext::Number;
22use crate::ser::{Begin, Describe, Emit, Serialize};
23
24pub struct Separated<const SEP: char = ',', A = Same>(PhantomData<fn() -> A>);
62
63pub struct TrimWhitespace<A = Same>(PhantomData<fn() -> A>);
94
95pub struct SkipBlank<A = Same>(PhantomData<fn() -> A>);
128
129#[derive(Clone, Copy)]
131enum TextOp {
132 Split(char),
134 Trim,
136}
137
138struct TextSink<'a, 'de> {
142 inner: SinkHandle<'a, 'de>,
143 op: TextOp,
144}
145
146impl<'a, 'de> TextSink<'a, 'de> {
147 fn handle(inner: SinkHandle<'a, 'de>, op: TextOp, state: &mut State) -> SinkHandle<'a, 'de> {
148 SinkHandle::arena(TextSink { inner, op }, state)
149 }
150}
151
152fn trimmed_range(text: &str) -> (usize, usize) {
154 let start = text.len() - text.trim_start().len();
155 let end = text.trim_end().len().max(start);
156 (start, end)
157}
158
159fn with_text<'x>(atom: &Atom<'_>, text: Text<'x>) -> Atom<'x> {
161 match atom {
162 Atom::Str(_) => Atom::Str(text),
163 _ => Atom::Lexical(text),
164 }
165}
166
167fn trim_atom(atom: Atom<'_>) -> Atom<'_> {
169 match atom {
170 Atom::Str(ref text) | Atom::Lexical(ref text) => {
171 let (start, end) = trimmed_range(text);
172 if start == 0 && end == text.len() {
173 return atom;
174 }
175 let trimmed = match text.borrowed_str() {
176 Some(text) => Text::borrowed(&text[start..end]),
177 None => Text::owned(&text[start..end]),
178 };
179 with_text(&atom, trimmed)
180 }
181 atom => atom,
182 }
183}
184
185fn split_into<'de>(
192 sink: &mut SinkHandle<'_, 'de>,
193 text: &str,
194 sep: char,
195 state: &mut State,
196) -> Result<(), Error> {
197 sink.seq(state)?;
198 if !text.is_empty() {
199 for piece in text.split(sep) {
200 let rv = sink.__private_value_atom(Atom::Lexical(Text::borrowed(piece)), state);
201 recover_element(sink, rv, state)?;
202 }
203 }
204 Ok(())
205}
206
207#[inline]
209fn recover_element(
210 sink: &mut SinkHandle<'_, '_>,
211 rv: Result<(), Error>,
212 state: &mut State,
213) -> Result<(), Error> {
214 match rv {
215 Ok(()) => Ok(()),
216 Err(err) if state.discards_errors => Err(err),
217 Err(err) => sink.recover(state.error_in_context(err), state),
218 }
219}
220
221fn split_borrowed_into<'de>(
225 sink: &mut SinkHandle<'_, 'de>,
226 text: &'de str,
227 sep: char,
228 state: &mut State,
229) -> Result<(), Error> {
230 sink.seq(state)?;
231 if !text.is_empty() {
232 for piece in text.split(sep) {
233 let rv =
234 sink.__private_borrowed_value_atom(Atom::Lexical(Text::borrowed(piece)), state);
235 recover_element(sink, rv, state)?;
236 }
237 }
238 Ok(())
239}
240
241impl<'a, 'de> Sink<'de> for TextSink<'a, 'de> {
242 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
243 match (self.op, atom) {
244 (TextOp::Split(sep), Atom::Str(text) | Atom::Lexical(text)) => {
245 split_into(&mut self.inner, &text, sep, state)
246 }
247 (TextOp::Trim, atom) => self.inner.atom(trim_atom(atom), state),
248 (_, atom) => self.inner.atom(atom, state),
249 }
250 }
251
252 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
253 match (self.op, atom) {
254 (TextOp::Split(sep), Atom::Str(ref text) | Atom::Lexical(ref text))
255 if text.is_borrowed() =>
256 {
257 let text = text.borrowed_str().unwrap_or_default();
258 split_borrowed_into(&mut self.inner, text, sep, state)
259 }
260 (TextOp::Split(sep), Atom::Str(text) | Atom::Lexical(text)) => {
261 split_into(&mut self.inner, &text, sep, state)
262 }
263 (TextOp::Trim, atom) => self.inner.borrowed_atom(trim_atom(atom), state),
264 (_, atom) => self.inner.borrowed_atom(atom, state),
265 }
266 }
267
268 fn map(&mut self, state: &mut State) -> Result<(), Error> {
269 self.inner.map(state)
270 }
271
272 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
273 self.inner.seq(state)
274 }
275
276 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
277 self.inner.next_key(state)
278 }
279
280 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
281 self.inner.next_value(state)
282 }
283
284 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
285 self.inner.__private_key_atom(atom, state)
286 }
287
288 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
289 self.inner.__private_value_atom(atom, state)
290 }
291
292 fn __private_borrowed_key_atom(
293 &mut self,
294 atom: Atom<'de>,
295 state: &mut State,
296 ) -> Result<(), Error> {
297 self.inner.__private_borrowed_key_atom(atom, state)
298 }
299
300 fn __private_borrowed_value_atom(
301 &mut self,
302 atom: Atom<'de>,
303 state: &mut State,
304 ) -> Result<(), Error> {
305 self.inner.__private_borrowed_value_atom(atom, state)
306 }
307
308 fn value_for_key(
309 &mut self,
310 key: &str,
311 state: &mut State,
312 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
313 self.inner.value_for_key(key, state)
314 }
315
316 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
317 self.inner.recover(err, state)
318 }
319
320 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
321 self.inner.finish(state)
322 }
323
324 fn expecting(&self) -> Cow<'_, str> {
325 self.inner.expecting()
326 }
327}
328
329#[inline]
331fn is_blank(atom: &Atom) -> bool {
332 matches!(atom, Atom::Str(text) | Atom::Lexical(text) if text.trim().is_empty())
333}
334
335enum SkipBlankSink<'a, 'de, T, A> {
341 Pending(&'a mut Option<T>, PhantomData<fn() -> A>),
342 Active(SinkHandle<'a, 'de>),
343}
344
345impl<'a, 'de, T: Send, A: Deserialize<'de, T>> SkipBlankSink<'a, 'de, T, A> {
346 fn active(&mut self, state: &mut State) -> &mut SinkHandle<'a, 'de> {
348 if let SkipBlankSink::Pending(..) = self
349 && let SkipBlankSink::Pending(out, _) =
350 core::mem::replace(self, SkipBlankSink::Active(SinkHandle::null()))
351 {
352 *self = SkipBlankSink::Active(A::deserialize_into(out, state));
353 }
354 match self {
355 SkipBlankSink::Active(sink) => sink,
356 SkipBlankSink::Pending(..) => unreachable!(),
357 }
358 }
359
360 fn skip(&mut self, atom: &Atom) -> bool {
362 if matches!(self, SkipBlankSink::Pending(..)) && is_blank(atom) {
363 *self = SkipBlankSink::Active(SinkHandle::null());
364 return true;
365 }
366 false
367 }
368}
369
370impl<'a, 'de, T: Send, A: Deserialize<'de, T>> Sink<'de> for SkipBlankSink<'a, 'de, T, A> {
371 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
372 if self.skip(&atom) {
373 return Ok(());
374 }
375 self.active(state).atom(atom, state)
376 }
377
378 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
379 if self.skip(&atom) {
380 return Ok(());
381 }
382 self.active(state).borrowed_atom(atom, state)
383 }
384
385 fn map(&mut self, state: &mut State) -> Result<(), Error> {
386 self.active(state).map(state)
387 }
388
389 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
390 self.active(state).seq(state)
391 }
392
393 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
394 self.active(state).next_key(state)
395 }
396
397 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
398 self.active(state).next_value(state)
399 }
400
401 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
402 self.active(state).__private_key_atom(atom, state)
403 }
404
405 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
406 self.active(state).__private_value_atom(atom, state)
407 }
408
409 fn __private_borrowed_key_atom(
410 &mut self,
411 atom: Atom<'de>,
412 state: &mut State,
413 ) -> Result<(), Error> {
414 self.active(state).__private_borrowed_key_atom(atom, state)
415 }
416
417 fn __private_borrowed_value_atom(
418 &mut self,
419 atom: Atom<'de>,
420 state: &mut State,
421 ) -> Result<(), Error> {
422 self.active(state)
423 .__private_borrowed_value_atom(atom, state)
424 }
425
426 fn value_for_key(
427 &mut self,
428 key: &str,
429 state: &mut State,
430 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
431 self.active(state).value_for_key(key, state)
432 }
433
434 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
435 self.active(state).recover(err, state)
436 }
437
438 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
439 self.active(state).finish(state)
440 }
441
442 fn expecting(&self) -> Cow<'_, str> {
443 match self {
444 SkipBlankSink::Active(sink) => sink.expecting(),
445 SkipBlankSink::Pending(..) => A::expecting(),
447 }
448 }
449}
450
451impl<'de, T: Send, A: Deserialize<'de, T>> Deserialize<'de, T> for SkipBlank<A> {
452 fn deserialize_into<'out>(
453 out: &'out mut Option<T>,
454 state: &mut State,
455 ) -> SinkHandle<'out, 'de> {
456 unsafe {
458 SinkHandle::arena_unbounded(SkipBlankSink::<T, A>::Pending(out, PhantomData), state)
459 }
460 }
461
462 fn expecting() -> Cow<'static, str> {
463 A::expecting()
464 }
465
466 fn describe_type(d: &mut dyn Describe) {
467 A::describe_type(d)
468 }
469
470 fn initial_value() -> Option<T> {
471 A::initial_value()
472 }
473
474 #[inline]
475 fn __private_atom_into(
476 out: &mut Option<T>,
477 atom: Atom,
478 state: &mut State,
479 ) -> Result<(), Error> {
480 if is_blank(&atom) {
481 return Ok(());
482 }
483 A::__private_atom_into(out, atom, state)
484 }
485
486 #[inline]
487 fn __private_borrowed_atom_into(
488 out: &mut Option<T>,
489 atom: Atom<'de>,
490 state: &mut State,
491 ) -> Result<(), Error> {
492 if is_blank(&atom) {
493 return Ok(());
494 }
495 A::__private_borrowed_atom_into(out, atom, state)
496 }
497
498 fn __private_is_bytes() -> bool {
499 A::__private_is_bytes()
500 }
501
502 fn __private_vec_from_bytes(bytes: Vec<u8>) -> Option<Vec<T>> {
503 A::__private_vec_from_bytes(bytes)
504 }
505
506 fn __private_array_from_bytes<const N: usize>(bytes: &[u8]) -> Option<[T; N]> {
507 A::__private_array_from_bytes::<N>(bytes)
508 }
509}
510
511impl<'de, T: Send, A: Deserialize<'de, T>> Deserialize<'de, T> for TrimWhitespace<A> {
512 fn deserialize_into<'out>(
513 out: &'out mut Option<T>,
514 state: &mut State,
515 ) -> SinkHandle<'out, 'de> {
516 TextSink::handle(A::deserialize_into(out, state), TextOp::Trim, state)
517 }
518
519 fn expecting() -> Cow<'static, str> {
520 A::expecting()
521 }
522
523 fn describe_type(d: &mut dyn Describe) {
524 A::describe_type(d)
525 }
526
527 fn initial_value() -> Option<T> {
528 A::initial_value()
529 }
530
531 #[inline]
532 fn __private_atom_into(
533 out: &mut Option<T>,
534 atom: Atom,
535 state: &mut State,
536 ) -> Result<(), Error> {
537 A::__private_atom_into(out, trim_atom(atom), state)
538 }
539
540 #[inline]
541 fn __private_borrowed_atom_into(
542 out: &mut Option<T>,
543 atom: Atom<'de>,
544 state: &mut State,
545 ) -> Result<(), Error> {
546 A::__private_borrowed_atom_into(out, trim_atom(atom), state)
547 }
548
549 fn __private_is_bytes() -> bool {
550 A::__private_is_bytes()
551 }
552
553 fn __private_vec_from_bytes(bytes: Vec<u8>) -> Option<Vec<T>> {
554 A::__private_vec_from_bytes(bytes)
555 }
556
557 fn __private_array_from_bytes<const N: usize>(bytes: &[u8]) -> Option<[T; N]> {
558 A::__private_array_from_bytes::<N>(bytes)
559 }
560}
561
562impl<T: ?Sized, A: Serialize<T>> Serialize<T> for TrimWhitespace<A> {
563 fn serialize<'a>(value: &'a T, state: &mut State) -> Result<Emit<'a>, Error> {
564 A::serialize(value, state)
565 }
566
567 fn finish(value: &T, state: &mut State) -> Result<(), Error> {
568 A::finish(value, state)
569 }
570
571 fn is_optional(value: &T) -> bool {
572 A::is_optional(value)
573 }
574
575 fn container_shape(value: &T) -> ContainerShape {
576 A::container_shape(value)
577 }
578
579 fn describe(value: &T, d: &mut dyn Describe) {
580 A::describe(value, d)
581 }
582
583 #[inline]
584 fn __private_begin<'a>(value: &'a T, state: &mut State) -> Result<Begin<'a>, Error> {
585 A::__private_begin(value, state)
586 }
587
588 fn __private_slice_as_bytes(val: &[T]) -> Option<Cow<'_, [u8]>>
589 where
590 T: Sized,
591 {
592 A::__private_slice_as_bytes(val)
593 }
594}
595
596impl<T: ?Sized, A: Serialize<T>> Serialize<T> for SkipBlank<A> {
597 fn serialize<'a>(value: &'a T, state: &mut State) -> Result<Emit<'a>, Error> {
598 A::serialize(value, state)
599 }
600
601 fn finish(value: &T, state: &mut State) -> Result<(), Error> {
602 A::finish(value, state)
603 }
604
605 fn is_optional(value: &T) -> bool {
606 A::is_optional(value)
607 }
608
609 fn container_shape(value: &T) -> ContainerShape {
610 A::container_shape(value)
611 }
612
613 fn describe(value: &T, d: &mut dyn Describe) {
614 A::describe(value, d)
615 }
616
617 #[inline]
618 fn __private_begin<'a>(value: &'a T, state: &mut State) -> Result<Begin<'a>, Error> {
619 A::__private_begin(value, state)
620 }
621
622 fn __private_slice_as_bytes(val: &[T]) -> Option<Cow<'_, [u8]>>
623 where
624 T: Sized,
625 {
626 A::__private_slice_as_bytes(val)
627 }
628}
629
630#[cold]
631fn unsupported_element(what: &str) -> Error {
632 Error::new(
633 ErrorKind::UnsupportedType,
634 format!(
635 "cannot join {}, elements must be strings, numbers, booleans or chars",
636 what
637 ),
638 )
639}
640
641fn atom_text<'a>(atom: &'a Atom<'_>) -> Result<Cow<'a, str>, Error> {
643 Ok(match *atom {
644 Atom::Bool(value) => Cow::Borrowed(if value { "true" } else { "false" }),
645 Atom::Str(ref value) | Atom::Lexical(ref value) => Cow::Borrowed(value),
646 Atom::Char(value) => Cow::Owned(value.to_string()),
647 Atom::U64(value) => Cow::Owned(value.to_string()),
648 Atom::I64(value) => Cow::Owned(value.to_string()),
649 Atom::F32(value) => Cow::Owned(value.to_string()),
650 Atom::F64(value) => Cow::Owned(value.to_string()),
651 Atom::Ext(ref ext) => {
652 if let Some(number) = ext.downcast_value_ref::<Number>() {
653 Cow::Owned(number.as_str().to_string())
655 } else if let Some(value) = ext.downcast_ref::<u128>() {
656 Cow::Owned(value.to_string())
657 } else if let Some(value) = ext.downcast_ref::<i128>() {
658 Cow::Owned(value.to_string())
659 } else {
660 match ext.fallback() {
661 Atom::Ext(_) => return Err(unsupported_element(ext.name())),
662 fallback => Cow::Owned(atom_text(&fallback)?.into_owned()),
663 }
664 }
665 }
666 ref atom => return Err(unsupported_element(atom.name())),
667 })
668}
669
670fn push_emit(emit: Emit<'_>, state: &mut State, out: &mut String) -> Result<(), Error> {
672 match emit {
673 Emit::Atom(ref atom) => out.push_str(&atom_text(atom)?),
674 Emit::Forward(handle) => {
675 push_emit(handle.get().serialize(state)?, state, out)?;
676 handle.get().finish(state)?;
677 }
678 Emit::Struct(_) | Emit::Map(_) => return Err(unsupported_element("map")),
679 Emit::Seq(_) => return Err(unsupported_element("sequence")),
680 }
681 Ok(())
682}
683
684fn join<'v, T: 'v, A: Serialize<T>>(
686 values: impl Iterator<Item = &'v T>,
687 sep: char,
688 state: &mut State,
689) -> Result<String, Error> {
690 let mut out = String::new();
691 let mut count = 0;
692 for value in values {
693 if count > 0 {
694 out.push(sep);
695 }
696 count += 1;
697 let start = out.len();
698 push_emit(A::serialize(value, state)?, state, &mut out)?;
699 A::finish(value, state)?;
700 if out[start..].contains(sep) {
701 return Err(Error::new(
702 ErrorKind::InvalidValue,
703 format!(
704 "cannot join {:?}, it contains the separator {:?}",
705 &out[start..],
706 sep
707 ),
708 ));
709 }
710 }
711 if count == 1 && out.is_empty() {
712 return Err(Error::new(
713 ErrorKind::InvalidValue,
714 "cannot join a single empty string, it would read back as no elements",
715 ));
716 }
717 Ok(out)
718}
719
720macro_rules! separated_impls {
722 ($([$($bound:tt)*] [$($ser_bound:tt)*] $target:ty => $adapter:ty;)*) => {
723 $(
724 impl<'de, $($bound)*, A: Deserialize<'de, T>, const SEP: char>
725 Deserialize<'de, $target> for Separated<SEP, A>
726 {
727 fn deserialize_into<'out>(out: &'out mut Option<$target>, state: &mut State) -> SinkHandle<'out, 'de> {
728 TextSink::handle(
729 <$adapter as Deserialize<'de, $target>>::deserialize_into(out, state),
730 TextOp::Split(SEP), state)
731 }
732
733 fn expecting() -> Cow<'static, str> {
734 <$adapter as Deserialize<'de, $target>>::expecting()
735 }
736 }
737
738 impl<$($ser_bound)*, A: Serialize<T>, const SEP: char> Serialize<$target>
739 for Separated<SEP, A>
740 {
741 fn serialize<'a>(
742 value: &'a $target,
743 state: &mut State,
744 ) -> Result<Emit<'a>, Error> {
745 let text = join::<T, A>(value.iter(), SEP, state)?;
746 Ok(Emit::Atom(Atom::Str(Text::owned(text))))
747 }
748
749 #[inline]
750 fn __private_begin<'a>(
751 value: &'a $target,
752 state: &mut State,
753 ) -> Result<Begin<'a>, Error> {
754 Ok(Begin::emit(
755 Self::serialize(value, state)?,
756 ContainerShape::new(),
757 false,
758 ))
759 }
760 }
761 )*
762 };
763}
764
765separated_impls! {
766 [T: Send] [T] Vec<T> => Vec<A>;
767 [T: Send] [T] VecDeque<T> => VecDeque<A>;
768 [T: Ord + Send] [T] BTreeSet<T> => BTreeSet<A>;
769}
770
771#[cfg(feature = "std")]
772separated_impls! {
773 [T: Hash + Eq + Send, H: BuildHasher + Default + Send] [T, H] HashSet<T, H> => HashSet<A>;
774}