1use crate::{
7 fill::Slot,
8 internal::{Internal, InternalVisitor},
9 std::{any::Any, fmt},
10 Error, ValueBag,
11};
12
13impl<'v> ValueBag<'v> {
14 pub fn capture_sval2<T>(value: &'v T) -> Self
19 where
20 T: value_bag_sval2::lib::Value + 'static,
21 {
22 Self::try_capture(value).unwrap_or(ValueBag {
23 inner: Internal::Sval2(value),
24 })
25 }
26
27 pub const fn from_sval2<T>(value: &'v T) -> Self
29 where
30 T: value_bag_sval2::lib::Value,
31 {
32 ValueBag {
33 inner: Internal::AnonSval2(value),
34 }
35 }
36
37 #[inline]
39 pub const fn from_dyn_sval2(value: &'v dyn Value) -> Self {
40 ValueBag {
41 inner: Internal::AnonSval2(value),
42 }
43 }
44}
45
46pub(crate) trait DowncastValue {
47 fn as_any(&self) -> &dyn Any;
48 fn as_super(&self) -> &dyn Value;
49}
50
51impl<T: value_bag_sval2::lib::Value + 'static> DowncastValue for T {
52 fn as_any(&self) -> &dyn Any {
53 self
54 }
55
56 fn as_super(&self) -> &dyn Value {
57 self
58 }
59}
60
61impl<'s, 'f> Slot<'s, 'f> {
62 pub fn fill_sval2<T>(self, value: T) -> Result<(), Error>
66 where
67 T: value_bag_sval2::lib::Value,
68 {
69 self.fill(|visitor| visitor.sval2(&value))
70 }
71}
72
73impl<'v> value_bag_sval2::lib::Value for ValueBag<'v> {
74 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
75 &'sval self,
76 s: &mut S,
77 ) -> value_bag_sval2::lib::Result {
78 use value_bag_sval2::lib_ref::ValueRef as _;
79
80 self.stream_ref(s)
81 }
82}
83
84impl<'sval> value_bag_sval2::lib_ref::ValueRef<'sval> for ValueBag<'sval> {
85 fn stream_ref<S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
86 &self,
87 s: &mut S,
88 ) -> value_bag_sval2::lib::Result {
89 struct Sval2Visitor<'a, S: ?Sized>(&'a mut S);
90
91 impl<'a, 'v, S: value_bag_sval2::lib::Stream<'v> + ?Sized> InternalVisitor<'v>
92 for Sval2Visitor<'a, S>
93 {
94 fn fill(&mut self, v: &dyn crate::fill::Fill) -> Result<(), Error> {
95 v.fill(crate::fill::Slot::new(self))
96 }
97
98 fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error> {
99 value_bag_sval2::fmt::stream_debug(self.0, v).map_err(Error::from_sval2)
100 }
101
102 fn display(&mut self, v: &dyn fmt::Display) -> Result<(), Error> {
103 value_bag_sval2::fmt::stream_display(self.0, v).map_err(Error::from_sval2)
104 }
105
106 fn u64(&mut self, v: u64) -> Result<(), Error> {
107 self.0.u64(v).map_err(Error::from_sval2)
108 }
109
110 fn i64(&mut self, v: i64) -> Result<(), Error> {
111 self.0.i64(v).map_err(Error::from_sval2)
112 }
113
114 fn u128(&mut self, v: &u128) -> Result<(), Error> {
115 self.0.u128(*v).map_err(Error::from_sval2)
116 }
117
118 fn i128(&mut self, v: &i128) -> Result<(), Error> {
119 self.0.i128(*v).map_err(Error::from_sval2)
120 }
121
122 fn f64(&mut self, v: f64) -> Result<(), Error> {
123 self.0.f64(v).map_err(Error::from_sval2)
124 }
125
126 fn bool(&mut self, v: bool) -> Result<(), Error> {
127 self.0.bool(v).map_err(Error::from_sval2)
128 }
129
130 fn char(&mut self, v: char) -> Result<(), Error> {
131 let mut buf = [0; 4];
132 let v = v.encode_utf8(&mut buf);
133
134 self.0.value_computed(v).map_err(Error::from_sval2)
135 }
136
137 fn str(&mut self, v: &str) -> Result<(), Error> {
138 self.0.value_computed(v).map_err(Error::from_sval2)
139 }
140
141 fn borrowed_str(&mut self, v: &'v str) -> Result<(), Error> {
142 self.0.value(v).map_err(Error::from_sval2)
143 }
144
145 fn none(&mut self) -> Result<(), Error> {
146 self.0.null().map_err(Error::from_sval2)
147 }
148
149 #[cfg(feature = "error")]
150 fn error(&mut self, v: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
151 self.display(&v)
152 }
153
154 fn sval2(&mut self, v: &dyn Value) -> Result<(), Error> {
155 self.0.value_computed(v).map_err(Error::from_sval2)
156 }
157
158 fn borrowed_sval2(&mut self, v: &'v dyn Value) -> Result<(), Error> {
159 self.0.value(v).map_err(Error::from_sval2)
160 }
161
162 #[cfg(feature = "serde1")]
163 fn serde1(
164 &mut self,
165 v: &dyn crate::internal::serde::v1::Serialize,
166 ) -> Result<(), Error> {
167 crate::internal::serde::v1::sval2(self.0, v)
168 }
169
170 #[cfg(feature = "seq")]
171 fn seq(&mut self, v: &dyn crate::internal::seq::Seq) -> Result<(), Error> {
172 self.0.seq_begin(None).map_err(Error::from_sval2)?;
173
174 let mut s = seq::StreamVisitor {
175 stream: &mut *self.0,
176 err: None,
177 };
178 v.visit(&mut s);
179 if let Some(e) = s.err {
180 return Err(Error::from_sval2(e));
181 }
182
183 self.0.seq_end().map_err(Error::from_sval2)
184 }
185
186 #[cfg(feature = "seq")]
187 fn borrowed_seq(&mut self, v: &'v dyn crate::internal::seq::Seq) -> Result<(), Error> {
188 self.0.seq_begin(None).map_err(Error::from_sval2)?;
189
190 let mut s = seq::StreamVisitor {
191 stream: &mut *self.0,
192 err: None,
193 };
194 v.borrowed_visit(&mut s);
195 if let Some(e) = s.err {
196 return Err(Error::from_sval2(e));
197 }
198
199 self.0.seq_end().map_err(Error::from_sval2)
200 }
201
202 fn poisoned(&mut self, msg: &'static str) -> Result<(), Error> {
203 Err(Error::msg(msg))
204 }
205 }
206
207 self.internal_visit(&mut Sval2Visitor(s))
208 .map_err(Error::into_sval2)?;
209
210 Ok(())
211 }
212}
213
214pub use value_bag_sval2::dynamic::Value;
215
216pub(in crate::internal) fn fmt(f: &mut fmt::Formatter, v: &dyn Value) -> Result<(), Error> {
217 value_bag_sval2::fmt::stream_to_fmt(f, v)?;
218 Ok(())
219}
220
221#[cfg(feature = "serde1")]
222pub(in crate::internal) fn serde1<S>(s: S, v: &dyn Value) -> Result<S::Ok, S::Error>
223where
224 S: value_bag_serde1::lib::Serializer,
225{
226 value_bag_sval2::serde1::serialize(s, v)
227}
228
229pub(crate) fn internal_visit(v: &dyn Value, visitor: &mut dyn InternalVisitor<'_>) -> bool {
230 let mut visitor = VisitorStream {
231 visitor,
232 text_buf: Default::default(),
233 };
234
235 value_bag_sval2::lib::stream_computed(&mut visitor, v).is_ok()
236}
237
238pub(crate) fn borrowed_internal_visit<'v>(
239 v: &'v dyn Value,
240 visitor: &mut dyn InternalVisitor<'v>,
241) -> bool {
242 let mut visitor = VisitorStream {
243 visitor,
244 text_buf: Default::default(),
245 };
246
247 value_bag_sval2::lib::stream(&mut visitor, v).is_ok()
248}
249
250struct VisitorStream<'a, 'v> {
251 visitor: &'a mut dyn InternalVisitor<'v>,
252 text_buf: value_bag_sval2::buffer::TextBuf<'v>,
253}
254
255impl<'a, 'v> value_bag_sval2::lib::Stream<'v> for VisitorStream<'a, 'v> {
256 fn null(&mut self) -> value_bag_sval2::lib::Result {
257 self.visitor.none().map_err(Error::into_sval2)
258 }
259
260 fn bool(&mut self, v: bool) -> value_bag_sval2::lib::Result {
261 self.visitor.bool(v).map_err(Error::into_sval2)
262 }
263
264 fn i64(&mut self, v: i64) -> value_bag_sval2::lib::Result {
265 self.visitor.i64(v).map_err(Error::into_sval2)
266 }
267
268 fn u64(&mut self, v: u64) -> value_bag_sval2::lib::Result {
269 self.visitor.u64(v).map_err(Error::into_sval2)
270 }
271
272 fn i128(&mut self, v: i128) -> value_bag_sval2::lib::Result {
273 self.visitor.i128(&v).map_err(Error::into_sval2)
274 }
275
276 fn u128(&mut self, v: u128) -> value_bag_sval2::lib::Result {
277 self.visitor.u128(&v).map_err(Error::into_sval2)
278 }
279
280 fn f64(&mut self, v: f64) -> value_bag_sval2::lib::Result {
281 self.visitor.f64(v).map_err(Error::into_sval2)
282 }
283
284 fn text_begin(&mut self, _: Option<usize>) -> value_bag_sval2::lib::Result {
285 self.text_buf.clear();
286 Ok(())
287 }
288
289 fn text_fragment_computed(&mut self, f: &str) -> value_bag_sval2::lib::Result {
290 self.text_buf
291 .push_fragment_computed(f)
292 .map_err(|_| value_bag_sval2::lib::Error::new())
293 }
294
295 fn text_fragment(&mut self, f: &'v str) -> value_bag_sval2::lib::Result {
296 self.text_buf
297 .push_fragment(f)
298 .map_err(|_| value_bag_sval2::lib::Error::new())
299 }
300
301 fn text_end(&mut self) -> value_bag_sval2::lib::Result {
302 if let Some(v) = self.text_buf.as_borrowed_str() {
303 self.visitor.borrowed_str(v).map_err(Error::into_sval2)
304 } else {
305 self.visitor
306 .str(self.text_buf.as_str())
307 .map_err(Error::into_sval2)
308 }
309 }
310
311 fn seq_begin(&mut self, _: Option<usize>) -> value_bag_sval2::lib::Result {
312 value_bag_sval2::lib::error()
313 }
314
315 fn seq_value_begin(&mut self) -> value_bag_sval2::lib::Result {
316 value_bag_sval2::lib::error()
317 }
318
319 fn seq_value_end(&mut self) -> value_bag_sval2::lib::Result {
320 value_bag_sval2::lib::error()
321 }
322
323 fn seq_end(&mut self) -> value_bag_sval2::lib::Result {
324 value_bag_sval2::lib::error()
325 }
326}
327
328impl Error {
329 pub(in crate::internal) fn from_sval2(_: value_bag_sval2::lib::Error) -> Self {
330 Error::msg("`sval` serialization failed")
331 }
332
333 pub(in crate::internal) fn into_sval2(self) -> value_bag_sval2::lib::Error {
334 value_bag_sval2::lib::Error::new()
335 }
336}
337
338#[cfg(feature = "seq")]
339pub(crate) mod seq {
340 use super::*;
341
342 use crate::{
343 internal::seq::{ExtendValue, Visitor},
344 std::ops::ControlFlow,
345 };
346
347 pub(super) struct StreamVisitor<'a, S: ?Sized> {
348 pub(super) stream: &'a mut S,
349 pub(super) err: Option<value_bag_sval2::lib::Error>,
350 }
351
352 impl<'a, 'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized> Visitor<'sval>
353 for StreamVisitor<'a, S>
354 {
355 fn element(&mut self, v: ValueBag) -> ControlFlow<()> {
356 if let Err(e) = self.stream.seq_value_begin() {
357 self.err = Some(e);
358 return ControlFlow::Break(());
359 }
360
361 if let Err(e) = value_bag_sval2::lib::stream_computed(&mut *self.stream, v) {
362 self.err = Some(e);
363 return ControlFlow::Break(());
364 }
365
366 if let Err(e) = self.stream.seq_value_end() {
367 self.err = Some(e);
368 return ControlFlow::Break(());
369 }
370
371 ControlFlow::Continue(())
372 }
373
374 fn borrowed_element(&mut self, v: ValueBag<'sval>) -> ControlFlow<()> {
375 if let Err(e) = self.stream.seq_value_begin() {
376 self.err = Some(e);
377 return ControlFlow::Break(());
378 }
379
380 if let Err(e) = value_bag_sval2::lib_ref::stream_ref(&mut *self.stream, v) {
381 self.err = Some(e);
382 return ControlFlow::Break(());
383 }
384
385 if let Err(e) = self.stream.seq_value_end() {
386 self.err = Some(e);
387 return ControlFlow::Break(());
388 }
389
390 ControlFlow::Continue(())
391 }
392 }
393
394 #[inline]
395 pub(crate) fn extend<'a, 'b, S: Default + ExtendValue<'a>>(v: &'b dyn Value) -> Option<S> {
396 let mut stream = Root {
397 seq: None,
398 text_buf: Default::default(),
399 depth: 0,
400 };
401
402 value_bag_sval2::lib::stream_computed(&mut stream, v).ok()?;
403
404 stream.seq
405 }
406
407 #[inline]
408 pub(crate) fn extend_borrowed<'a, S: Default + ExtendValue<'a>>(v: &'a dyn Value) -> Option<S> {
409 let mut stream = Root {
410 seq: None,
411 text_buf: Default::default(),
412 depth: 0,
413 };
414
415 value_bag_sval2::lib::stream(&mut stream, v).ok()?;
416
417 stream.seq
418 }
419
420 struct Root<'v, S> {
421 seq: Option<S>,
422 text_buf: value_bag_sval2::buffer::TextBuf<'v>,
423 depth: usize,
424 }
425
426 fn extend_borrowed_internal<'sval>(
427 seq: Option<&mut impl ExtendValue<'sval>>,
428 depth: usize,
429 v: impl Into<ValueBag<'sval>>,
430 ) -> value_bag_sval2::lib::Result {
431 if depth != 1 {
432 return Ok(());
433 }
434
435 if let Some(seq) = seq {
436 seq.extend_borrowed(v.into().inner);
437
438 Ok(())
439 } else {
440 value_bag_sval2::lib::error()
441 }
442 }
443
444 fn extend_internal<'a, 'sval>(
445 seq: Option<&mut impl ExtendValue<'sval>>,
446 depth: usize,
447 v: impl Into<ValueBag<'a>>,
448 ) -> value_bag_sval2::lib::Result {
449 if depth != 1 {
450 return Ok(());
451 }
452
453 if let Some(seq) = seq {
454 seq.extend(v.into().inner);
455
456 Ok(())
457 } else {
458 value_bag_sval2::lib::error()
459 }
460 }
461
462 impl<'sval, S: Default + ExtendValue<'sval>> value_bag_sval2::lib::Stream<'sval>
463 for Root<'sval, S>
464 {
465 fn null(&mut self) -> value_bag_sval2::lib::Result {
466 extend_borrowed_internal(self.seq.as_mut(), self.depth, ())
467 }
468
469 fn bool(&mut self, v: bool) -> value_bag_sval2::lib::Result {
470 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
471 }
472
473 fn i64(&mut self, v: i64) -> value_bag_sval2::lib::Result {
474 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
475 }
476
477 fn u64(&mut self, v: u64) -> value_bag_sval2::lib::Result {
478 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
479 }
480
481 fn i128(&mut self, v: i128) -> value_bag_sval2::lib::Result {
482 #[cfg(feature = "inline-i128")]
483 {
484 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
485 }
486 #[cfg(not(feature = "inline-i128"))]
487 {
488 extend_internal(self.seq.as_mut(), self.depth, &v)
489 }
490 }
491
492 fn u128(&mut self, v: u128) -> value_bag_sval2::lib::Result {
493 #[cfg(feature = "inline-i128")]
494 {
495 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
496 }
497 #[cfg(not(feature = "inline-i128"))]
498 {
499 extend_internal(self.seq.as_mut(), self.depth, &v)
500 }
501 }
502
503 fn f64(&mut self, v: f64) -> value_bag_sval2::lib::Result {
504 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
505 }
506
507 fn text_begin(&mut self, _: Option<usize>) -> value_bag_sval2::lib::Result {
508 self.text_buf.clear();
509 Ok(())
510 }
511
512 fn text_fragment_computed(&mut self, f: &str) -> value_bag_sval2::lib::Result {
513 self.text_buf
514 .push_fragment_computed(f)
515 .map_err(|_| value_bag_sval2::lib::Error::new())
516 }
517
518 fn text_fragment(&mut self, f: &'sval str) -> value_bag_sval2::lib::Result {
519 self.text_buf
520 .push_fragment(f)
521 .map_err(|_| value_bag_sval2::lib::Error::new())
522 }
523
524 fn text_end(&mut self) -> value_bag_sval2::lib::Result {
525 if let Some(v) = self.text_buf.as_borrowed_str() {
526 extend_borrowed_internal(self.seq.as_mut(), self.depth, v)
527 } else {
528 let v = self.text_buf.as_str();
529 extend_internal(self.seq.as_mut(), self.depth, v)
530 }
531 }
532
533 fn seq_begin(&mut self, _: Option<usize>) -> value_bag_sval2::lib::Result {
534 if self.seq.is_none() {
535 self.seq = Some(S::default());
536 }
537
538 self.depth += 1;
539
540 if self.depth > 1 {
544 if let Some(ref mut seq) = self.seq {
545 seq.extend_borrowed(ValueBag::from(()).inner);
546 }
547 }
548
549 Ok(())
550 }
551
552 fn seq_value_begin(&mut self) -> value_bag_sval2::lib::Result {
553 Ok(())
554 }
555
556 fn seq_value_end(&mut self) -> value_bag_sval2::lib::Result {
557 Ok(())
558 }
559
560 fn seq_end(&mut self) -> value_bag_sval2::lib::Result {
561 self.depth -= 1;
562
563 Ok(())
564 }
565 }
566}
567
568#[cfg(feature = "owned")]
569pub(crate) mod owned {
570 impl value_bag_sval2::lib::Value for crate::OwnedValueBag {
571 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
572 &'sval self,
573 s: &mut S,
574 ) -> value_bag_sval2::lib::Result {
575 value_bag_sval2::lib_ref::ValueRef::stream_ref(&self.by_ref(), s)
576 }
577 }
578
579 pub(crate) type OwnedValue = value_bag_sval2::buffer::Value<'static>;
580
581 pub(crate) fn buffer(
582 v: impl value_bag_sval2::lib::Value,
583 ) -> Result<OwnedValue, value_bag_sval2::buffer::Error> {
584 OwnedValue::collect_owned(v)
585 }
586}
587
588impl<'v> From<&'v dyn Value> for ValueBag<'v> {
589 #[inline]
590 fn from(v: &'v dyn Value) -> Self {
591 ValueBag::from_dyn_sval2(v)
592 }
593}
594
595impl<'v> From<Option<&'v dyn Value>> for ValueBag<'v> {
596 #[inline]
597 fn from(v: Option<&'v dyn Value>) -> Self {
598 ValueBag::from_option(v)
599 }
600}
601
602impl<'v, 'u> From<&'v &'u dyn Value> for ValueBag<'v>
603where
604 'u: 'v,
605{
606 #[inline]
607 fn from(v: &'v &'u dyn Value) -> Self {
608 ValueBag::from_dyn_sval2(*v)
609 }
610}
611
612#[cfg(test)]
613mod tests {
614 #[cfg(target_arch = "wasm32")]
615 use wasm_bindgen_test::*;
616
617 use super::*;
618 use crate::test::*;
619
620 #[test]
621 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
622 fn sval2_capture() {
623 assert_eq!(
624 ValueBag::capture_sval2(&42u64).to_test_token(),
625 TestToken::U64(42)
626 );
627 }
628
629 #[test]
630 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
631 fn sval2_fill() {
632 assert_eq!(
633 ValueBag::from_fill(&|slot: Slot| slot.fill_sval2(42u64)).to_test_token(),
634 TestToken::Sval { version: 2 },
635 );
636 }
637
638 #[test]
639 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
640 fn sval2_capture_cast() {
641 assert_eq!(
642 42u64,
643 ValueBag::capture_sval2(&42u64)
644 .to_u64()
645 .expect("invalid value")
646 );
647
648 assert_eq!(
649 "a string",
650 ValueBag::capture_sval2(&"a string")
651 .to_borrowed_str()
652 .expect("invalid value")
653 );
654
655 #[cfg(feature = "std")]
656 assert_eq!(
657 "a string",
658 ValueBag::capture_sval2(&"a string")
659 .to_str()
660 .expect("invalid value")
661 );
662 }
663
664 #[test]
665 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
666 fn sval2_capture_cast_borrowed_str() {
667 struct Number<'a>(&'a str);
668
669 impl<'a> value_bag_sval2::lib::Value for Number<'a> {
670 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
671 &'sval self,
672 stream: &mut S,
673 ) -> value_bag_sval2::lib::Result {
674 stream.tagged_begin(Some(&value_bag_sval2::lib::tags::NUMBER), None, None)?;
675 stream.value(self.0)?;
676 stream.tagged_end(Some(&value_bag_sval2::lib::tags::NUMBER), None, None)
677 }
678 }
679
680 assert_eq!(
681 "123.456e789",
682 ValueBag::capture_sval2(&Number("123.456e789"))
683 .to_borrowed_str()
684 .expect("invalid value")
685 );
686 }
687
688 #[test]
689 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
690 fn sval2_from_cast() {
691 assert_eq!(
692 42u64,
693 ValueBag::from_sval2(&42u64)
694 .to_u64()
695 .expect("invalid value")
696 );
697
698 #[cfg(feature = "std")]
699 assert_eq!(
700 "a string",
701 ValueBag::from_sval2(&"a string")
702 .to_str()
703 .expect("invalid value")
704 );
705 }
706
707 #[test]
708 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
709 fn sval2_downcast() {
710 #[derive(Debug, PartialEq, Eq)]
711 struct Timestamp(usize);
712
713 impl value_bag_sval2::lib::Value for Timestamp {
714 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
715 &'sval self,
716 stream: &mut S,
717 ) -> value_bag_sval2::lib::Result {
718 stream.u64(self.0 as u64)
719 }
720 }
721
722 let ts = Timestamp(42);
723
724 assert_eq!(
725 &ts,
726 ValueBag::capture_sval2(&ts)
727 .downcast_ref::<Timestamp>()
728 .expect("invalid value")
729 );
730 }
731
732 #[test]
733 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
734 fn sval2_structured() {
735 let value = ValueBag::from(42u64);
736
737 value_bag_sval2::test::assert_tokens(&value, &[value_bag_sval2::test::Token::U64(42)]);
738 }
739
740 #[test]
741 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
742 fn sval2_debug() {
743 struct TestSval;
744
745 impl value_bag_sval2::lib::Value for TestSval {
746 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
747 &'sval self,
748 stream: &mut S,
749 ) -> value_bag_sval2::lib::Result {
750 stream.u64(42)
751 }
752 }
753
754 assert_eq!(
755 format!("{:04?}", 42u64),
756 format!("{:04?}", ValueBag::capture_sval2(&TestSval)),
757 );
758 }
759
760 #[test]
761 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
762 fn sval2_visit() {
763 ValueBag::from_sval2(&42u64)
764 .visit(TestVisit::default())
765 .expect("failed to visit value");
766 ValueBag::from_sval2(&-42i64)
767 .visit(TestVisit::default())
768 .expect("failed to visit value");
769 ValueBag::from_sval2(&11f64)
770 .visit(TestVisit::default())
771 .expect("failed to visit value");
772 ValueBag::from_sval2(&true)
773 .visit(TestVisit::default())
774 .expect("failed to visit value");
775 ValueBag::from_sval2(&"some borrowed string")
776 .visit(TestVisit::default())
777 .expect("failed to visit value");
778 ValueBag::from_sval2(&'n')
779 .visit(TestVisit {
780 str: "n",
781 ..Default::default()
782 })
783 .expect("failed to visit value");
784 }
785
786 #[test]
787 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
788 #[cfg(feature = "serde1")]
789 fn sval2_serde1() {
790 use value_bag_serde1::test::{assert_ser_tokens, Token};
791
792 struct TestSval;
793
794 impl value_bag_sval2::lib::Value for TestSval {
795 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
796 &'sval self,
797 stream: &mut S,
798 ) -> value_bag_sval2::lib::Result {
799 stream.u64(42)
800 }
801 }
802
803 assert_ser_tokens(&ValueBag::capture_sval2(&TestSval), &[Token::U64(42)]);
804 }
805
806 #[cfg(feature = "seq")]
807 mod seq_support {
808 use super::*;
809
810 use crate::std::vec::Vec;
811
812 #[test]
813 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
814 fn sval2_stream_borrowed_str_seq() {
815 let value = ValueBag::from_seq_slice(&["a", "b", "c"]);
816
817 value_bag_sval2::test::assert_tokens(&value, {
818 use value_bag_sval2::test::Token::*;
819
820 &[
821 SeqBegin(None),
822 SeqValueBegin,
823 TextBegin(Some(1)),
824 TextFragment("a"),
825 TextEnd,
826 SeqValueEnd,
827 SeqValueBegin,
828 TextBegin(Some(1)),
829 TextFragment("b"),
830 TextEnd,
831 SeqValueEnd,
832 SeqValueBegin,
833 TextBegin(Some(1)),
834 TextFragment("c"),
835 TextEnd,
836 SeqValueEnd,
837 SeqEnd,
838 ]
839 });
840 }
841
842 #[test]
843 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
844 fn sval2_stream_str_seq() {
845 let value = ValueBag::from_fill(&|slot: Slot| slot.fill_seq_slice(&["a", "b", "c"]));
846
847 value_bag_sval2::test::assert_tokens(&value, {
848 use value_bag_sval2::test::Token::*;
849
850 &[
851 SeqBegin(None),
852 SeqValueBegin,
853 TextBegin(Some(1)),
854 TextFragmentComputed("a".into()),
855 TextEnd,
856 SeqValueEnd,
857 SeqValueBegin,
858 TextBegin(Some(1)),
859 TextFragmentComputed("b".into()),
860 TextEnd,
861 SeqValueEnd,
862 SeqValueBegin,
863 TextBegin(Some(1)),
864 TextFragmentComputed("c".into()),
865 TextEnd,
866 SeqValueEnd,
867 SeqEnd,
868 ]
869 });
870 }
871
872 #[test]
873 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
874 #[cfg(feature = "alloc")]
875 fn sval2_borrowed_str_to_seq() {
876 use crate::std::borrow::Cow;
877
878 assert_eq!(
879 vec![
880 Some(Cow::Borrowed("a string 1")),
881 Some(Cow::Borrowed("a string 2")),
882 Some(Cow::Borrowed("a string 3"))
883 ],
884 ValueBag::capture_sval2(&[&"a string 1", &"a string 2", &"a string 3",])
885 .to_str_seq::<Vec<Option<Cow<str>>>>()
886 .expect("invalid value")
887 );
888 }
889
890 #[test]
891 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
892 fn sval2_to_seq() {
893 assert_eq!(
894 vec![Some(1.0), None, None, Some(2.0), Some(3.0), None],
895 ValueBag::capture_sval2(&[
896 &1.0 as &dyn Value,
897 &true as &dyn Value,
898 &[1.0, 2.0, 3.0] as &dyn Value,
899 &2.0 as &dyn Value,
900 &3.0 as &dyn Value,
901 &"a string" as &dyn Value,
902 ])
903 .to_f64_seq::<Vec<Option<f64>>>()
904 .expect("invalid value")
905 );
906 }
907
908 #[test]
909 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
910 fn sval2_as_seq() {
911 assert_eq!(
912 vec![1.0, 2.0, 3.0],
913 ValueBag::capture_sval2(&[1.0, 2.0, 3.0,]).as_f64_seq::<Vec<f64>>()
914 );
915 }
916 }
917
918 #[cfg(feature = "std")]
919 mod std_support {
920 use super::*;
921
922 use crate::std::borrow::ToOwned;
923
924 #[test]
925 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
926 fn sval2_cast() {
927 assert_eq!(
928 "a string",
929 ValueBag::capture_sval2(&"a string".to_owned())
930 .by_ref()
931 .to_str()
932 .expect("invalid value")
933 );
934 }
935 }
936
937 #[cfg(feature = "owned")]
938 mod owned_support {
939 use super::*;
940
941 #[test]
942 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
943 fn sval2_to_owned_poison() {
944 struct Kaboom;
945
946 impl value_bag_sval2::lib::Value for Kaboom {
947 fn stream<'sval, S: value_bag_sval2::lib::Stream<'sval> + ?Sized>(
948 &'sval self,
949 _: &mut S,
950 ) -> value_bag_sval2::lib::Result {
951 value_bag_sval2::lib::error()
952 }
953 }
954
955 let value = ValueBag::capture_sval2(&Kaboom)
956 .to_owned()
957 .by_ref()
958 .to_test_token();
959
960 assert_eq!(
961 TestToken::Poisoned("failed to buffer the value".into()),
962 value
963 );
964 }
965 }
966}