1use crate::{
2 fill::Slot,
3 internal::{Internal, InternalVisitor},
4 std::{any::Any, fmt, marker::PhantomData, mem, ops::ControlFlow},
5 Error, ValueBag,
6};
7
8#[cfg(feature = "alloc")]
9use crate::std::{string::String, vec::Vec};
10
11impl<'v> ValueBag<'v> {
12 pub fn from_seq_slice<I, T>(value: &'v I) -> Self
14 where
15 I: AsRef<[T]>,
16 &'v T: Into<ValueBag<'v>> + 'v,
17 {
18 ValueBag {
19 inner: Internal::AnonSeq(SeqSlice::new_ref(value)),
20 }
21 }
22
23 pub(crate) const fn from_dyn_seq(value: &'v dyn Seq) -> Self {
24 ValueBag {
25 inner: Internal::AnonSeq(value),
26 }
27 }
28
29 pub fn to_u64_seq<S: Default + Extend<Option<u64>>>(&self) -> Option<S> {
36 self.inner
37 .extend::<ExtendPrimitive<S, u64>>()
38 .map(|seq| seq.into_inner())
39 }
40
41 pub fn to_i64_seq<S: Default + Extend<Option<i64>>>(&self) -> Option<S> {
48 self.inner
49 .extend::<ExtendPrimitive<S, i64>>()
50 .map(|seq| seq.into_inner())
51 }
52
53 pub fn to_u128_seq<S: Default + Extend<Option<u128>>>(&self) -> Option<S> {
60 self.inner
61 .extend::<ExtendPrimitive<S, u128>>()
62 .map(|seq| seq.into_inner())
63 }
64
65 pub fn to_i128_seq<S: Default + Extend<Option<i128>>>(&self) -> Option<S> {
72 self.inner
73 .extend::<ExtendPrimitive<S, i128>>()
74 .map(|seq| seq.into_inner())
75 }
76
77 pub fn to_f64_seq<S: Default + Extend<Option<f64>>>(&self) -> Option<S> {
84 self.inner
85 .extend::<ExtendPrimitive<S, f64>>()
86 .map(|seq| seq.into_inner())
87 }
88
89 pub fn as_f64_seq<S: Default + Extend<f64>>(&self) -> S {
102 #[derive(Default)]
103 struct ExtendF64<S>(S);
104
105 impl<'a, S: Extend<f64>> ExtendValue<'a> for ExtendF64<S> {
106 fn extend(&mut self, inner: Internal<'_>) {
107 self.0.extend(Some(ValueBag { inner }.as_f64()))
108 }
109 }
110
111 self.inner
112 .extend::<ExtendF64<S>>()
113 .map(|seq| seq.0)
114 .unwrap_or_default()
115 }
116
117 pub fn to_bool_seq<S: Default + Extend<Option<bool>>>(&self) -> Option<S> {
124 self.inner
125 .extend::<ExtendPrimitive<S, bool>>()
126 .map(|seq| seq.into_inner())
127 }
128
129 pub fn to_char_seq<S: Default + Extend<Option<char>>>(&self) -> Option<S> {
136 self.inner
137 .extend::<ExtendPrimitive<S, char>>()
138 .map(|seq| seq.into_inner())
139 }
140
141 #[inline]
148 pub fn to_borrowed_str_seq<S: Default + Extend<Option<&'v str>>>(&self) -> Option<S> {
149 #[derive(Default)]
150 struct ExtendStr<'a, S>(S, PhantomData<&'a str>);
151
152 impl<'a, S: Extend<Option<&'a str>>> ExtendValue<'a> for ExtendStr<'a, S> {
153 fn extend<'b>(&mut self, _: Internal<'b>) {
154 self.0.extend(Some(None::<&'a str>))
155 }
156
157 fn extend_borrowed(&mut self, inner: Internal<'a>) {
158 self.0.extend(Some(ValueBag { inner }.to_borrowed_str()))
159 }
160 }
161
162 self.inner.extend::<ExtendStr<'v, S>>().map(|seq| seq.0)
163 }
164}
165
166impl<'s, 'f> Slot<'s, 'f> {
167 pub fn fill_seq_slice<I, T>(self, value: &'f I) -> Result<(), Error>
171 where
172 I: AsRef<[T]>,
173 &'f T: Into<ValueBag<'f>> + 'f,
174 {
175 self.fill(|visitor| visitor.seq(SeqSlice::new_ref(value)))
176 }
177}
178
179#[repr(transparent)]
186struct SeqSlice<'a, I: ?Sized, T>(PhantomData<&'a [T]>, I);
187
188impl<'a, I: AsRef<[T]> + ?Sized + 'a, T> SeqSlice<'a, I, T> {
189 fn new_ref(v: &'a I) -> &'a SeqSlice<'a, I, T> {
190 unsafe { &*(v as *const I as *const SeqSlice<'a, I, T>) }
192 }
193
194 fn as_ref<'b>(&'b self) -> &'a [T] {
195 let inner = unsafe { mem::transmute::<&'b I, &'a I>(&self.1) };
198
199 inner.as_ref()
200 }
201}
202
203impl<'a, I, T> Seq for SeqSlice<'a, I, T>
204where
205 I: AsRef<[T]> + ?Sized + 'a,
206 &'a T: Into<ValueBag<'a>>,
207{
208 fn visit(&self, visitor: &mut dyn Visitor<'_>) {
209 for v in self.as_ref().iter() {
210 if let ControlFlow::Break(()) = visitor.element(v.into()) {
211 return;
212 }
213 }
214 }
215
216 fn borrowed_visit<'v>(&'v self, visitor: &mut dyn Visitor<'v>) {
217 for v in self.as_ref().iter() {
218 if let ControlFlow::Break(()) = visitor.borrowed_element(v.into()) {
219 return;
220 }
221 }
222 }
223}
224
225pub(crate) trait Seq {
226 fn visit(&self, visitor: &mut dyn Visitor<'_>);
227
228 fn borrowed_visit<'v>(&'v self, visitor: &mut dyn Visitor<'v>) {
229 self.visit(visitor)
230 }
231}
232
233impl<'a, S: Seq + ?Sized> Seq for &'a S {
234 fn visit(&self, visitor: &mut dyn Visitor<'_>) {
235 (**self).visit(visitor)
236 }
237
238 fn borrowed_visit<'v>(&'v self, visitor: &mut dyn Visitor<'v>) {
239 (**self).borrowed_visit(visitor)
240 }
241}
242
243pub(crate) trait Visitor<'v> {
244 fn element(&mut self, v: ValueBag) -> ControlFlow<()>;
245
246 fn borrowed_element(&mut self, v: ValueBag<'v>) -> ControlFlow<()> {
247 self.element(v)
248 }
249}
250
251impl<'a, 'v, T: Visitor<'v> + ?Sized> Visitor<'v> for &'a mut T {
252 fn element(&mut self, v: ValueBag) -> ControlFlow<()> {
253 (**self).element(v)
254 }
255
256 fn borrowed_element(&mut self, v: ValueBag<'v>) -> ControlFlow<()> {
257 (**self).borrowed_element(v)
258 }
259}
260
261pub(crate) trait DowncastSeq {
262 #[allow(dead_code)]
264 fn as_any(&self) -> &dyn Any;
265 fn as_super(&self) -> &dyn Seq;
266}
267
268impl<T: Seq + 'static> DowncastSeq for T {
269 fn as_any(&self) -> &dyn Any {
270 self
271 }
272
273 fn as_super(&self) -> &dyn Seq {
274 self
275 }
276}
277
278impl<'a> Seq for dyn DowncastSeq + Send + Sync + 'a {
279 fn visit(&self, visitor: &mut dyn Visitor<'_>) {
280 self.as_super().visit(visitor)
281 }
282}
283
284macro_rules! convert_primitive(
285 ($($t:ty,)*) => {
286 $(
287 impl<'v, const N: usize> From<&'v [$t; N]> for ValueBag<'v> {
288 fn from(v: &'v [$t; N]) -> Self {
289 ValueBag::from_seq_slice(v)
290 }
291 }
292
293 impl<'v, const N: usize> From<Option<&'v [$t; N]>> for ValueBag<'v> {
294 fn from(v: Option<&'v [$t; N]>) -> Self {
295 ValueBag::from_option(v)
296 }
297 }
298
299 impl<'a, 'v> From<&'v &'a [$t]> for ValueBag<'v> {
300 fn from(v: &'v &'a [$t]) -> Self {
301 ValueBag::from_seq_slice(v)
302 }
303 }
304
305 impl<'a, 'v> From<Option<&'v &'a [$t]>> for ValueBag<'v> {
306 fn from(v: Option<&'v &'a [$t]>) -> Self {
307 ValueBag::from_option(v)
308 }
309 }
310
311 #[cfg(feature = "alloc")]
312 impl<'v> From<&'v Vec<$t>> for ValueBag<'v> {
313 fn from(v: &'v Vec<$t>) -> Self {
314 ValueBag::from_seq_slice(v)
315 }
316 }
317
318 #[cfg(feature = "alloc")]
319 impl<'v> From<Option<&'v Vec<$t>>> for ValueBag<'v> {
320 fn from(v: Option<&'v Vec<$t>>) -> Self {
321 ValueBag::from_option(v)
322 }
323 }
324 )*
325 }
326);
327
328convert_primitive![
329 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64, bool, char,
330];
331
332impl<'v, 'a, const N: usize> From<&'v [&'a str; N]> for ValueBag<'v> {
333 fn from(v: &'v [&'a str; N]) -> Self {
334 ValueBag::from_seq_slice(v)
335 }
336}
337
338impl<'v, 'a, const N: usize> From<Option<&'v [&'a str; N]>> for ValueBag<'v> {
339 fn from(v: Option<&'v [&'a str; N]>) -> Self {
340 ValueBag::from_option(v)
341 }
342}
343
344impl<'v, 'a, 'b> From<&'v &'a [&'b str]> for ValueBag<'v> {
345 fn from(v: &'v &'a [&'b str]) -> Self {
346 ValueBag::from_seq_slice(v)
347 }
348}
349
350impl<'v, 'a, 'b> From<Option<&'v &'a [&'b str]>> for ValueBag<'v> {
351 fn from(v: Option<&'v &'a [&'b str]>) -> Self {
352 ValueBag::from_option(v)
353 }
354}
355
356#[cfg(feature = "alloc")]
357impl<'v> From<&'v Vec<String>> for ValueBag<'v> {
358 fn from(v: &'v Vec<String>) -> Self {
359 ValueBag::from_seq_slice(v)
360 }
361}
362
363#[cfg(feature = "alloc")]
364impl<'v> From<Option<&'v Vec<String>>> for ValueBag<'v> {
365 fn from(v: Option<&'v Vec<String>>) -> Self {
366 ValueBag::from_option(v)
367 }
368}
369
370#[derive(Default)]
371pub(crate) struct ExtendPrimitive<S, T>(S, PhantomData<T>);
372
373impl<S, T> ExtendPrimitive<S, T> {
374 pub fn into_inner(self) -> S {
375 self.0
376 }
377}
378
379impl<'a, S: Extend<Option<T>>, T: for<'b> TryFrom<ValueBag<'b>>> ExtendValue<'a>
380 for ExtendPrimitive<S, T>
381{
382 fn extend(&mut self, inner: Internal) {
383 self.0.extend(Some(ValueBag { inner }.try_into().ok()))
384 }
385}
386
387#[allow(dead_code)]
388pub(crate) trait ExtendValue<'v> {
389 fn extend(&mut self, v: Internal);
390
391 fn extend_borrowed(&mut self, v: Internal<'v>) {
392 self.extend(v);
393 }
394}
395
396struct ExtendVisitor<S>(S);
397
398impl<'v, S: ExtendValue<'v>> Visitor<'v> for ExtendVisitor<S> {
399 fn element(&mut self, v: ValueBag) -> ControlFlow<()> {
400 self.0.extend(v.inner);
401 ControlFlow::Continue(())
402 }
403
404 fn borrowed_element(&mut self, v: ValueBag<'v>) -> ControlFlow<()> {
405 self.0.extend_borrowed(v.inner);
406 ControlFlow::Continue(())
407 }
408}
409
410impl<'v> Internal<'v> {
411 #[inline]
412 pub(crate) fn extend<S: Default + ExtendValue<'v>>(&self) -> Option<S> {
413 struct SeqVisitor<S>(Option<S>);
414
415 impl<'v, S: Default + ExtendValue<'v>> InternalVisitor<'v> for SeqVisitor<S> {
416 #[inline]
417 fn fill(&mut self, v: &dyn crate::fill::Fill) -> Result<(), Error> {
418 v.fill(Slot::new(self))
419 }
420
421 #[inline]
422 fn debug(&mut self, _: &dyn fmt::Debug) -> Result<(), Error> {
423 Ok(())
424 }
425
426 #[inline]
427 fn display(&mut self, _: &dyn fmt::Display) -> Result<(), Error> {
428 Ok(())
429 }
430
431 #[inline]
432 fn u64(&mut self, _: u64) -> Result<(), Error> {
433 Ok(())
434 }
435
436 #[inline]
437 fn i64(&mut self, _: i64) -> Result<(), Error> {
438 Ok(())
439 }
440
441 #[inline]
442 fn u128(&mut self, _: &u128) -> Result<(), Error> {
443 Ok(())
444 }
445
446 #[inline]
447 fn i128(&mut self, _: &i128) -> Result<(), Error> {
448 Ok(())
449 }
450
451 #[inline]
452 fn f64(&mut self, _: f64) -> Result<(), Error> {
453 Ok(())
454 }
455
456 #[inline]
457 fn bool(&mut self, _: bool) -> Result<(), Error> {
458 Ok(())
459 }
460
461 #[inline]
462 fn char(&mut self, _: char) -> Result<(), Error> {
463 Ok(())
464 }
465
466 #[inline]
467 fn str(&mut self, _: &str) -> Result<(), Error> {
468 Ok(())
469 }
470
471 #[inline]
472 fn none(&mut self) -> Result<(), Error> {
473 Ok(())
474 }
475
476 #[cfg(feature = "error")]
477 #[inline]
478 fn error(&mut self, _: &dyn crate::internal::error::Error) -> Result<(), Error> {
479 Ok(())
480 }
481
482 #[cfg(feature = "sval2")]
483 #[inline]
484 fn sval2(&mut self, v: &dyn crate::internal::sval::v2::Value) -> Result<(), Error> {
485 self.0 = crate::internal::sval::v2::seq::extend(v);
486
487 Ok(())
488 }
489
490 #[cfg(feature = "sval2")]
491 #[inline]
492 fn borrowed_sval2(
493 &mut self,
494 v: &'v dyn crate::internal::sval::v2::Value,
495 ) -> Result<(), Error> {
496 self.0 = crate::internal::sval::v2::seq::extend_borrowed(v);
497
498 Ok(())
499 }
500
501 #[cfg(feature = "serde1")]
502 #[inline]
503 fn serde1(
504 &mut self,
505 v: &dyn crate::internal::serde::v1::Serialize,
506 ) -> Result<(), Error> {
507 self.0 = crate::internal::serde::v1::seq::extend(v);
508
509 Ok(())
510 }
511
512 fn seq(&mut self, seq: &dyn Seq) -> Result<(), Error> {
513 let mut s = ExtendVisitor(S::default());
514 seq.visit(&mut s);
515 self.0 = Some(s.0);
516
517 Ok(())
518 }
519
520 fn borrowed_seq(&mut self, seq: &'v dyn Seq) -> Result<(), Error> {
521 let mut s = ExtendVisitor(S::default());
522 seq.borrowed_visit(&mut s);
523 self.0 = Some(s.0);
524
525 Ok(())
526 }
527
528 fn poisoned(&mut self, _: &'static str) -> Result<(), Error> {
529 Ok(())
530 }
531 }
532
533 let mut visitor = SeqVisitor(None);
534 let _ = self.internal_visit(&mut visitor);
535
536 visitor.0
537 }
538}
539
540#[cfg(feature = "alloc")]
541mod alloc_support {
542 use super::*;
543
544 use crate::std::borrow::Cow;
545
546 impl<'v> ValueBag<'v> {
547 #[inline]
554 pub fn to_str_seq<S: Default + Extend<Option<Cow<'v, str>>>>(&self) -> Option<S> {
555 #[derive(Default)]
556 struct ExtendStr<'a, S>(S, PhantomData<Cow<'a, str>>);
557
558 impl<'a, S: Extend<Option<Cow<'a, str>>>> ExtendValue<'a> for ExtendStr<'a, S> {
559 fn extend(&mut self, inner: Internal<'_>) {
560 self.0.extend(Some(
561 ValueBag { inner }
562 .to_str()
563 .map(|s| Cow::Owned(s.into_owned())),
564 ))
565 }
566
567 fn extend_borrowed(&mut self, inner: Internal<'a>) {
568 self.0.extend(Some(ValueBag { inner }.to_str()))
569 }
570 }
571
572 self.inner.extend::<ExtendStr<'v, S>>().map(|seq| seq.0)
573 }
574 }
575}
576
577#[cfg(feature = "owned")]
578pub(crate) mod owned {
579 use super::*;
580
581 use crate::{owned::OwnedValueBag, std::boxed::Box};
582
583 #[derive(Clone)]
584 pub(crate) struct OwnedSeq(Box<[OwnedValueBag]>);
585
586 impl Seq for OwnedSeq {
587 fn visit(&self, visitor: &mut dyn Visitor<'_>) {
588 for item in self.0.iter() {
589 if let ControlFlow::Break(()) = visitor.element(item.by_ref()) {
590 return;
591 }
592 }
593 }
594 }
595
596 pub(crate) fn buffer(v: &dyn Seq) -> Result<OwnedSeq, Error> {
597 struct BufferVisitor(Vec<OwnedValueBag>);
598
599 impl<'v> Visitor<'v> for BufferVisitor {
600 fn element(&mut self, v: ValueBag) -> ControlFlow<()> {
601 self.0.push(v.to_owned());
602 ControlFlow::Continue(())
603 }
604 }
605
606 let mut buf = BufferVisitor(Vec::new());
607 v.visit(&mut buf);
608 Ok(OwnedSeq(buf.0.into_boxed_slice()))
609 }
610}
611
612#[cfg(test)]
613mod tests {
614 #[cfg(target_arch = "wasm32")]
615 use wasm_bindgen_test::*;
616
617 use std::vec::Vec;
618
619 use super::*;
620
621 #[test]
622 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
623 fn to_u64_seq() {
624 assert_eq!(
625 Some(vec![Some(1u64), Some(2u64), Some(3u64)]),
626 ValueBag::from(&[1u8, 2u8, 3u8]).to_u64_seq::<Vec<Option<u64>>>()
627 );
628
629 assert_eq!(
630 Some(vec![Some(1u64), Some(2u64), Some(3u64)]),
631 ValueBag::from(&[1u16, 2u16, 3u16]).to_u64_seq::<Vec<Option<u64>>>()
632 );
633
634 assert_eq!(
635 Some(vec![Some(1u64), Some(2u64), Some(3u64)]),
636 ValueBag::from(&[1u32, 2u32, 3u32]).to_u64_seq::<Vec<Option<u64>>>()
637 );
638
639 assert_eq!(
640 Some(vec![Some(1u64), Some(2u64), Some(3u64)]),
641 ValueBag::from(&[1u64, 2u64, 3u64]).to_u64_seq::<Vec<Option<u64>>>()
642 );
643 }
644
645 #[test]
646 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
647 fn to_i64_seq() {
648 assert_eq!(
649 Some(vec![Some(1i64), Some(2i64), Some(3i64)]),
650 ValueBag::from(&[1i8, 2i8, 3i8]).to_i64_seq::<Vec<Option<i64>>>()
651 );
652
653 assert_eq!(
654 Some(vec![Some(1i64), Some(2i64), Some(3i64)]),
655 ValueBag::from(&[1i16, 2i16, 3i16]).to_i64_seq::<Vec<Option<i64>>>()
656 );
657
658 assert_eq!(
659 Some(vec![Some(1i64), Some(2i64), Some(3i64)]),
660 ValueBag::from(&[1i32, 2i32, 3i32]).to_i64_seq::<Vec<Option<i64>>>()
661 );
662
663 assert_eq!(
664 Some(vec![Some(1i64), Some(2i64), Some(3i64)]),
665 ValueBag::from(&[1i64, 2i64, 3i64]).to_i64_seq::<Vec<Option<i64>>>()
666 );
667 }
668
669 #[test]
670 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
671 fn to_f64_seq() {
672 assert_eq!(
673 Some(vec![Some(1.0f64), Some(2.0f64), Some(3.0f64)]),
674 ValueBag::from(&[1.0f64, 2.0f64, 3.0f64]).to_f64_seq::<Vec<Option<f64>>>()
675 );
676 }
677
678 #[test]
679 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
680 fn as_f64_seq() {
681 assert_eq!(
682 Vec::<f64>::new(),
683 ValueBag::from(1.0f64).as_f64_seq::<Vec<f64>>()
684 );
685
686 assert_eq!(
687 vec![1.0f64, 2.0f64, 3.0f64],
688 ValueBag::from(&[1, 2, 3]).as_f64_seq::<Vec<f64>>()
689 );
690 }
691
692 #[test]
693 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
694 fn to_u128_seq() {
695 assert_eq!(
696 Some(vec![Some(1u128), Some(2u128), Some(3u128)]),
697 ValueBag::from(&[1u128, 2u128, 3u128]).to_u128_seq::<Vec<Option<u128>>>()
698 );
699 }
700
701 #[test]
702 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
703 fn to_i128_seq() {
704 assert_eq!(
705 Some(vec![Some(1i128), Some(2i128), Some(3i128)]),
706 ValueBag::from(&[1i128, 2i128, 3i128]).to_i128_seq::<Vec<Option<i128>>>()
707 );
708 }
709
710 #[test]
711 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
712 fn to_bool_seq() {
713 assert_eq!(
714 Some(vec![Some(true), Some(false)]),
715 ValueBag::from(&[true, false]).to_bool_seq::<Vec<Option<bool>>>()
716 );
717 }
718
719 #[test]
720 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
721 fn to_char_seq() {
722 assert_eq!(
723 Some(vec![Some('a'), Some('b'), Some('c')]),
724 ValueBag::from(&['a', 'b', 'c']).to_char_seq::<Vec<Option<char>>>()
725 );
726 }
727
728 #[test]
729 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
730 fn to_borrowed_str_seq() {
731 let v = ["a", "b", "c"];
732 let v = ValueBag::from(&v);
733
734 assert_eq!(
735 Some(vec![Some("a"), Some("b"), Some("c")]),
736 v.to_borrowed_str_seq::<Vec<Option<&str>>>()
737 );
738
739 let v = ValueBag::from_fill(&|slot: Slot| slot.fill_seq_slice(&["a", "b", "c"]));
740
741 assert_eq!(
742 Some(vec![None, None, None]),
743 v.to_borrowed_str_seq::<Vec<Option<&str>>>()
744 );
745 }
746
747 #[cfg(feature = "alloc")]
748 mod alloc_support {
749 use super::*;
750
751 use crate::std::borrow::Cow;
752
753 #[test]
754 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
755 fn to_str_seq() {
756 let v = ["a", "b", "c"];
757 let v = ValueBag::from(&v);
758
759 assert_eq!(
760 Some(vec![
761 Some(Cow::Borrowed("a")),
762 Some(Cow::Borrowed("b")),
763 Some(Cow::Borrowed("c"))
764 ]),
765 v.to_str_seq::<Vec<Option<Cow<str>>>>()
766 );
767
768 let v = ValueBag::from_fill(&|slot: Slot| slot.fill_seq_slice(&["a", "b", "c"]));
769
770 assert_eq!(
771 Some(vec![
772 Some(Cow::Owned("a".into())),
773 Some(Cow::Owned("b".into())),
774 Some(Cow::Owned("c".into()))
775 ]),
776 v.to_str_seq::<Vec<Option<Cow<str>>>>()
777 );
778 }
779 }
780}