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