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