1use crate::{
2 std::fmt::{self, Write as _},
3 Error,
4};
5
6#[cfg(feature = "alloc")]
7use crate::std::{
8 borrow::{Cow, ToOwned},
9 mem,
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct TextBuf<'sval> {
20 buf: FragmentBuf<'sval, str>,
21}
22
23impl<'sval> TextBuf<'sval> {
24 #[inline(always)]
28 pub fn new() -> Self {
29 TextBuf {
30 buf: FragmentBuf::new(""),
31 }
32 }
33
34 pub fn collect(value: &'sval (impl sval::Value + ?Sized)) -> Result<Self, Error> {
38 let mut collector = TextCollector {
39 buf: TextBuf::new(),
40 err: None,
41 };
42
43 value
44 .stream(&mut collector)
45 .map_err(|_| collector.err.unwrap())?;
46
47 Ok(collector.buf)
48 }
49
50 pub fn collect_display(value: impl fmt::Display) -> Result<Self, Error> {
54 let mut buf = TextBuf::new();
55 buf.push_display(value)?;
56
57 Ok(buf)
58 }
59
60 #[inline(always)]
64 pub fn clear(&mut self) {
65 *self = Default::default();
66 }
67
68 #[inline(always)]
72 pub fn push_fragment(&mut self, fragment: &'sval str) -> Result<(), Error> {
73 self.buf.push(fragment)
74 }
75
76 #[inline(always)]
83 pub fn push_fragment_computed(&mut self, fragment: &str) -> Result<(), Error> {
84 self.buf.push_computed(fragment)
85 }
86
87 pub fn push_display(&mut self, value: impl fmt::Display) -> Result<(), Error> {
94 struct Writer<'a, 'sval> {
95 buf: &'a mut TextBuf<'sval>,
96 err: Option<Error>,
97 }
98
99 impl<'a, 'sval> fmt::Write for Writer<'a, 'sval> {
100 fn write_str(&mut self, s: &str) -> fmt::Result {
101 match self.buf.push_fragment_computed(s) {
102 Ok(()) => Ok(()),
103 Err(e) => {
104 self.err = Some(e);
105 Err(fmt::Error)
106 }
107 }
108 }
109 }
110
111 let mut writer = Writer {
112 buf: self,
113 err: None,
114 };
115
116 write!(&mut writer, "{}", value).map_err(|_| {
117 writer
118 .err
119 .unwrap_or_else(|| Error::invalid_value("formatting failed"))
120 })
121 }
122
123 #[inline(always)]
127 pub fn as_borrowed_str(&self) -> Option<&'sval str> {
128 self.buf.as_borrowed_inner()
129 }
130
131 #[inline(always)]
135 pub fn as_str(&self) -> &str {
136 self.buf.as_inner()
137 }
138
139 #[cfg(feature = "alloc")]
140 pub(crate) fn into_owned_in_place(&mut self) -> &mut TextBuf<'static> {
141 let TextBuf { ref mut buf } = self;
142
143 crate::assert_static(buf.into_owned_in_place());
144
145 unsafe { mem::transmute::<&mut TextBuf<'sval>, &mut TextBuf<'static>>(self) }
147 }
148}
149
150struct TextCollector<'a> {
151 buf: TextBuf<'a>,
152 err: Option<Error>,
153}
154
155impl<'a> TextCollector<'a> {
156 fn try_catch(&mut self, f: impl FnOnce(&mut TextBuf<'a>) -> Result<(), Error>) -> sval::Result {
157 match f(&mut self.buf) {
158 Ok(()) => Ok(()),
159 Err(e) => self.fail(e),
160 }
161 }
162
163 fn fail(&mut self, err: Error) -> sval::Result {
164 self.err = Some(err);
165 sval::error()
166 }
167}
168
169impl<'a> sval::Stream<'a> for TextCollector<'a> {
170 fn text_begin(&mut self, _: Option<usize>) -> sval::Result {
171 Ok(())
172 }
173
174 fn text_fragment(&mut self, fragment: &'a str) -> sval::Result {
175 self.try_catch(|buf| buf.push_fragment(fragment))
176 }
177
178 fn text_fragment_computed(&mut self, fragment: &str) -> sval::Result {
179 self.try_catch(|buf| buf.push_fragment_computed(fragment))
180 }
181
182 fn text_end(&mut self) -> sval::Result {
183 Ok(())
184 }
185
186 fn null(&mut self) -> sval::Result {
187 self.fail(Error::unsupported("text", "null"))
188 }
189
190 fn bool(&mut self, _: bool) -> sval::Result {
191 self.fail(Error::unsupported("text", "boolean"))
192 }
193
194 fn i64(&mut self, _: i64) -> sval::Result {
195 self.fail(Error::unsupported("text", "integer"))
196 }
197
198 fn f64(&mut self, _: f64) -> sval::Result {
199 self.fail(Error::unsupported("text", "floating point"))
200 }
201
202 fn seq_begin(&mut self, _: Option<usize>) -> sval::Result {
203 self.fail(Error::unsupported("text", "sequence"))
204 }
205
206 fn seq_value_begin(&mut self) -> sval::Result {
207 self.fail(Error::unsupported("text", "sequence"))
208 }
209
210 fn seq_value_end(&mut self) -> sval::Result {
211 self.fail(Error::unsupported("text", "sequence"))
212 }
213
214 fn seq_end(&mut self) -> sval::Result {
215 self.fail(Error::unsupported("text", "sequence"))
216 }
217}
218
219impl<'sval> fmt::Write for TextBuf<'sval> {
220 fn write_str(&mut self, s: &str) -> fmt::Result {
221 self.push_fragment_computed(s).map_err(|_| fmt::Error)
222 }
223}
224
225impl<'sval> Default for TextBuf<'sval> {
226 #[inline(always)]
227 fn default() -> Self {
228 TextBuf::new()
229 }
230}
231
232impl<'sval> From<&'sval str> for TextBuf<'sval> {
233 #[inline(always)]
234 fn from(fragment: &'sval str) -> Self {
235 TextBuf {
236 buf: FragmentBuf::new(fragment),
237 }
238 }
239}
240
241impl<'sval> AsRef<str> for TextBuf<'sval> {
242 #[inline(always)]
243 fn as_ref(&self) -> &str {
244 self.as_str()
245 }
246}
247
248impl<'a> sval::Value for TextBuf<'a> {
249 fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
250 self.as_str().stream(stream)
251 }
252}
253
254impl<'sval> sval_ref::ValueRef<'sval> for TextBuf<'sval> {
255 fn stream_ref<S: sval::Stream<'sval> + ?Sized>(&self, stream: &mut S) -> sval::Result {
256 match self.as_borrowed_str() {
257 Some(v) => stream.value(v),
258 None => {
259 let v = self.as_str();
260
261 stream.text_begin(Some(v.len()))?;
262 stream.text_fragment_computed(v)?;
263 stream.text_end()
264 }
265 }
266 }
267}
268
269#[derive(Debug, Clone, PartialEq, Eq)]
276pub struct BinaryBuf<'sval> {
277 buf: FragmentBuf<'sval, [u8]>,
278}
279
280impl<'sval> BinaryBuf<'sval> {
281 #[inline(always)]
285 pub fn new() -> Self {
286 BinaryBuf {
287 buf: FragmentBuf::new(&[]),
288 }
289 }
290
291 pub fn collect(value: &'sval (impl sval::Value + ?Sized)) -> Result<Self, Error> {
295 let mut collector = BinaryCollector {
296 buf: BinaryBuf::new(),
297 err: None,
298 };
299
300 value
301 .stream(&mut collector)
302 .map_err(|_| collector.err.unwrap())?;
303
304 Ok(collector.buf)
305 }
306
307 #[inline(always)]
311 pub fn clear(&mut self) {
312 *self = Default::default();
313 }
314
315 #[inline(always)]
319 pub fn push_fragment(&mut self, fragment: &'sval [u8]) -> Result<(), Error> {
320 self.buf.push(fragment)
321 }
322
323 #[inline(always)]
330 pub fn push_fragment_computed(&mut self, fragment: &[u8]) -> Result<(), Error> {
331 self.buf.push_computed(fragment)
332 }
333
334 #[inline(always)]
338 pub fn as_borrowed_slice(&self) -> Option<&'sval [u8]> {
339 self.buf.as_borrowed_inner()
340 }
341
342 #[inline(always)]
346 pub fn as_slice(&self) -> &[u8] {
347 self.buf.as_inner()
348 }
349
350 #[cfg(feature = "alloc")]
351 pub(crate) fn into_owned_in_place(&mut self) -> &mut BinaryBuf<'static> {
352 let BinaryBuf { ref mut buf } = self;
353
354 crate::assert_static(buf.into_owned_in_place());
355
356 unsafe { mem::transmute::<&mut BinaryBuf<'sval>, &mut BinaryBuf<'static>>(self) }
358 }
359}
360
361struct BinaryCollector<'a> {
362 buf: BinaryBuf<'a>,
363 err: Option<Error>,
364}
365
366impl<'a> BinaryCollector<'a> {
367 fn try_catch(
368 &mut self,
369 f: impl FnOnce(&mut BinaryBuf<'a>) -> Result<(), Error>,
370 ) -> sval::Result {
371 match f(&mut self.buf) {
372 Ok(()) => Ok(()),
373 Err(e) => self.fail(e),
374 }
375 }
376
377 fn fail(&mut self, err: Error) -> sval::Result {
378 self.err = Some(err);
379 sval::error()
380 }
381}
382
383impl<'a> sval::Stream<'a> for BinaryCollector<'a> {
384 fn binary_begin(&mut self, _: Option<usize>) -> sval::Result {
385 Ok(())
386 }
387
388 fn binary_fragment(&mut self, fragment: &'a [u8]) -> sval::Result {
389 self.try_catch(|buf| buf.push_fragment(fragment))
390 }
391
392 fn binary_fragment_computed(&mut self, fragment: &[u8]) -> sval::Result {
393 self.try_catch(|buf| buf.push_fragment_computed(fragment))
394 }
395
396 fn binary_end(&mut self) -> sval::Result {
397 Ok(())
398 }
399
400 fn text_begin(&mut self, _: Option<usize>) -> sval::Result {
401 self.fail(Error::unsupported("binary", "text"))
402 }
403
404 fn text_fragment_computed(&mut self, _: &str) -> sval::Result {
405 self.fail(Error::unsupported("binary", "text"))
406 }
407
408 fn text_end(&mut self) -> sval::Result {
409 self.fail(Error::unsupported("binary", "text"))
410 }
411
412 fn null(&mut self) -> sval::Result {
413 self.fail(Error::unsupported("binary", "null"))
414 }
415
416 fn bool(&mut self, _: bool) -> sval::Result {
417 self.fail(Error::unsupported("binary", "boolean"))
418 }
419
420 fn u8(&mut self, value: u8) -> sval::Result {
421 self.try_catch(|buf| buf.push_fragment_computed(&[value]))
422 }
423
424 fn i64(&mut self, _: i64) -> sval::Result {
425 self.fail(Error::unsupported("binary", "integer"))
426 }
427
428 fn f64(&mut self, _: f64) -> sval::Result {
429 self.fail(Error::unsupported("binary", "floating point"))
430 }
431
432 fn map_begin(&mut self, _: Option<usize>) -> sval::Result {
433 self.fail(Error::unsupported("binary", "map"))
434 }
435
436 fn seq_begin(&mut self, _: Option<usize>) -> sval::Result {
437 Ok(())
438 }
439
440 fn seq_value_begin(&mut self) -> sval::Result {
441 Ok(())
442 }
443
444 fn seq_value_end(&mut self) -> sval::Result {
445 Ok(())
446 }
447
448 fn seq_end(&mut self) -> sval::Result {
449 Ok(())
450 }
451}
452
453impl<'sval> Default for BinaryBuf<'sval> {
454 #[inline(always)]
455 fn default() -> Self {
456 BinaryBuf::new()
457 }
458}
459
460impl<'sval> From<&'sval [u8]> for BinaryBuf<'sval> {
461 #[inline(always)]
462 fn from(fragment: &'sval [u8]) -> Self {
463 BinaryBuf {
464 buf: FragmentBuf::new(fragment),
465 }
466 }
467}
468
469impl<'sval, const N: usize> From<&'sval [u8; N]> for BinaryBuf<'sval> {
470 fn from(fragment: &'sval [u8; N]) -> Self {
471 BinaryBuf {
472 buf: FragmentBuf::new(fragment),
473 }
474 }
475}
476
477impl<'sval> AsRef<[u8]> for BinaryBuf<'sval> {
478 #[inline(always)]
479 fn as_ref(&self) -> &[u8] {
480 self.as_slice()
481 }
482}
483
484impl<'a> sval::Value for BinaryBuf<'a> {
485 fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
486 sval::BinarySlice::new(self.as_slice()).stream(stream)
487 }
488}
489
490impl<'sval> sval_ref::ValueRef<'sval> for BinaryBuf<'sval> {
491 fn stream_ref<S: sval::Stream<'sval> + ?Sized>(&self, stream: &mut S) -> sval::Result {
492 match self.as_borrowed_slice() {
493 Some(v) => stream.value(sval::BinarySlice::new(v)),
494 None => stream.value_computed(sval::BinarySlice::new(self.as_slice())),
495 }
496 }
497}
498
499#[cfg(not(feature = "alloc"))]
500trait Fragment {
501 #[inline(always)]
502 fn to_fragment<'sval>(&'sval self) -> &'sval Self {
503 self
504 }
505
506 fn can_replace(&self) -> bool;
507}
508
509#[cfg(feature = "alloc")]
510trait Fragment: ToOwned {
511 #[inline(always)]
512 fn to_fragment<'sval>(&'sval self) -> Cow<'sval, Self> {
513 Cow::Borrowed(self)
514 }
515
516 fn extend(buf: &mut Cow<Self>, fragment: &Self);
517
518 fn can_replace(&self) -> bool;
519
520 fn into_owned_in_place<'a, 'sval>(buf: &'a mut Cow<'sval, Self>) -> &'a mut Cow<'static, Self> {
521 if let Cow::Borrowed(v) = buf {
522 *buf = Cow::Owned(v.to_owned());
523 }
524
525 unsafe { mem::transmute::<&mut Cow<'_, Self>, &mut Cow<'static, Self>>(buf) }
527 }
528}
529
530impl Fragment for str {
531 #[cfg(feature = "alloc")]
532 #[inline(always)]
533 fn extend(buf: &mut Cow<Self>, fragment: &Self) {
534 buf.to_mut().push_str(fragment);
535 }
536
537 fn can_replace(&self) -> bool {
538 self.len() == 0
539 }
540}
541
542impl Fragment for [u8] {
543 #[cfg(feature = "alloc")]
544 #[inline(always)]
545 fn extend(buf: &mut Cow<Self>, fragment: &Self) {
546 buf.to_mut().extend(fragment);
547 }
548
549 fn can_replace(&self) -> bool {
550 self.len() == 0
551 }
552}
553
554struct FragmentBuf<'sval, T: ?Sized + Fragment> {
555 #[cfg(not(feature = "alloc"))]
556 value: &'sval T,
557 #[cfg(feature = "alloc")]
558 value: Cow<'sval, T>,
559}
560
561#[cfg(not(feature = "alloc"))]
562impl<'sval, T: ?Sized + Fragment> Clone for FragmentBuf<'sval, T> {
563 fn clone(&self) -> Self {
564 FragmentBuf { value: self.value }
565 }
566}
567
568#[cfg(feature = "alloc")]
569impl<'sval, T: ?Sized + Fragment> Clone for FragmentBuf<'sval, T>
570where
571 T::Owned: Clone,
572{
573 fn clone(&self) -> Self {
574 FragmentBuf {
575 value: self.value.clone(),
576 }
577 }
578}
579
580#[cfg(not(feature = "alloc"))]
581impl<'sval, T: ?Sized + Fragment + fmt::Debug> fmt::Debug for FragmentBuf<'sval, T> {
582 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
583 self.value.fmt(f)
584 }
585}
586
587#[cfg(feature = "alloc")]
588impl<'sval, T: ?Sized + Fragment + fmt::Debug> fmt::Debug for FragmentBuf<'sval, T>
589where
590 T::Owned: fmt::Debug,
591{
592 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
593 self.value.fmt(f)
594 }
595}
596
597#[cfg(not(feature = "alloc"))]
598impl<'sval, T: ?Sized + Fragment + PartialEq> PartialEq for FragmentBuf<'sval, T> {
599 fn eq(&self, other: &Self) -> bool {
600 self.value == other.value
601 }
602}
603
604#[cfg(feature = "alloc")]
605impl<'sval, T: ?Sized + Fragment + PartialEq> PartialEq for FragmentBuf<'sval, T>
606where
607 T::Owned: PartialEq,
608{
609 fn eq(&self, other: &Self) -> bool {
610 self.value == other.value
611 }
612}
613
614#[cfg(not(feature = "alloc"))]
615impl<'sval, T: ?Sized + Fragment + PartialEq> Eq for FragmentBuf<'sval, T> {}
616
617#[cfg(feature = "alloc")]
618impl<'sval, T: ?Sized + Fragment + Eq> Eq for FragmentBuf<'sval, T> where T::Owned: Eq {}
619
620impl<'sval, T: ?Sized + Fragment> FragmentBuf<'sval, T> {
621 #[inline(always)]
622 fn new(value: &'sval T) -> Self {
623 FragmentBuf {
624 value: value.to_fragment(),
625 }
626 }
627
628 #[inline(always)]
629 fn push(&mut self, fragment: &'sval T) -> Result<(), Error> {
630 if self.value.can_replace() {
631 self.value = fragment.to_fragment();
632
633 Ok(())
634 } else {
635 self.push_computed(fragment)
636 }
637 }
638
639 #[inline(always)]
640 fn push_computed(&mut self, fragment: &T) -> Result<(), Error> {
641 #[cfg(feature = "alloc")]
642 {
643 Fragment::extend(&mut self.value, fragment);
644
645 Ok(())
646 }
647
648 #[cfg(not(feature = "alloc"))]
649 {
650 let _ = fragment;
651 Err(Error::no_alloc("computed fragment"))
652 }
653 }
654
655 #[inline(always)]
656 fn as_borrowed_inner(&self) -> Option<&'sval T> {
657 #[cfg(feature = "alloc")]
658 {
659 match self.value {
660 Cow::Borrowed(value) => Some(value),
661 Cow::Owned(_) => None,
662 }
663 }
664
665 #[cfg(not(feature = "alloc"))]
666 {
667 Some(self.value)
668 }
669 }
670
671 #[inline(always)]
672 fn as_inner(&self) -> &T {
673 #[cfg(feature = "alloc")]
674 {
675 &*self.value
676 }
677
678 #[cfg(not(feature = "alloc"))]
679 {
680 self.value
681 }
682 }
683
684 #[cfg(feature = "alloc")]
685 pub(crate) fn into_owned_in_place(&mut self) -> &mut FragmentBuf<'static, T> {
686 crate::assert_static(Fragment::into_owned_in_place(&mut self.value));
687
688 unsafe { mem::transmute::<&mut FragmentBuf<'sval, T>, &mut FragmentBuf<'static, T>>(self) }
690 }
691}
692
693#[cfg(test)]
694mod tests {
695 use super::*;
696 use sval_ref::ValueRef;
697
698 #[test]
699 fn text_buf_empty() {
700 assert_eq!("", TextBuf::new().as_borrowed_str().unwrap());
701 }
702
703 #[test]
704 fn binary_buf_empty() {
705 assert_eq!(&[] as &[u8], BinaryBuf::new().as_borrowed_slice().unwrap());
706 }
707
708 #[test]
709 fn text_fragment_replace() {
710 let mut buf = TextBuf::new();
711
712 assert_eq!("", buf.as_str());
713 assert_eq!(Some(""), buf.as_borrowed_str());
714
715 buf.push_fragment("abc").unwrap();
716
717 assert_eq!("abc", buf.as_str());
718 assert_eq!(Some("abc"), buf.as_borrowed_str());
719 }
720
721 #[test]
722 fn text_fragment_clear() {
723 let mut buf = TextBuf::new();
724
725 buf.push_fragment("abc").unwrap();
726 buf.clear();
727
728 assert_eq!("", buf.as_str());
729 }
730
731 #[test]
732 fn binary_fragment_replace() {
733 let mut buf = BinaryBuf::new();
734
735 assert_eq!(b"" as &[u8], buf.as_slice());
736 assert_eq!(Some(b"" as &[u8]), buf.as_borrowed_slice());
737
738 buf.push_fragment(b"abc").unwrap();
739
740 assert_eq!(b"abc", buf.as_slice());
741 assert_eq!(Some(b"abc" as &[u8]), buf.as_borrowed_slice());
742 }
743
744 #[test]
745 fn binary_fragment_clear() {
746 let mut buf = BinaryBuf::new();
747
748 buf.push_fragment(b"abc").unwrap();
749 buf.clear();
750
751 assert_eq!(b"", buf.as_slice());
752 }
753
754 #[test]
755 #[cfg(feature = "alloc")]
756 fn text_fragment_computed() {
757 let mut buf = TextBuf::new();
758
759 buf.push_fragment_computed("abc").unwrap();
760
761 assert_eq!("abc", buf.as_str());
762 assert_eq!(None, buf.as_borrowed_str());
763 }
764
765 #[test]
766 #[cfg(feature = "alloc")]
767 fn binary_fragment_computed() {
768 let mut buf = BinaryBuf::new();
769
770 buf.push_fragment_computed(b"abc").unwrap();
771
772 assert_eq!(b"abc" as &[u8], buf.as_slice());
773 assert_eq!(None, buf.as_borrowed_slice());
774 }
775
776 #[test]
777 #[cfg(feature = "alloc")]
778 fn text_fragment_extend() {
779 let mut buf = TextBuf::new();
780
781 buf.push_fragment("abc").unwrap();
782 buf.push_fragment("def").unwrap();
783
784 assert_eq!("abcdef", buf.as_str());
785 assert_eq!(None, buf.as_borrowed_str());
786 }
787
788 #[test]
789 #[cfg(feature = "alloc")]
790 fn binary_fragment_extend() {
791 let mut buf = BinaryBuf::new();
792
793 buf.push_fragment(b"abc").unwrap();
794 buf.push_fragment(b"def").unwrap();
795
796 assert_eq!(b"abcdef" as &[u8], buf.as_slice());
797 assert_eq!(None, buf.as_borrowed_slice());
798 }
799
800 #[test]
801 #[cfg(feature = "alloc")]
802 fn collect_text_buf() {
803 let buf = TextBuf::collect("a string").unwrap();
804
805 assert_eq!(Some("a string"), buf.as_borrowed_str());
806 }
807
808 #[test]
809 #[cfg(feature = "alloc")]
810 fn collect_binary_buf() {
811 let buf = BinaryBuf::collect(sval::BinarySlice::new(b"a string")).unwrap();
812
813 assert_eq!(Some(b"a string" as &[u8]), buf.as_borrowed_slice());
814 }
815
816 #[test]
817 #[cfg(feature = "alloc")]
818 fn collect_binary_buf_seq() {
819 let buf = BinaryBuf::collect(b"a string").unwrap();
820
821 assert_eq!(b"a string" as &[u8], buf.as_slice());
822 }
823
824 #[test]
825 fn stream_text_buf() {
826 let mut buf = TextBuf::new();
827 buf.push_fragment("abc").unwrap();
828
829 sval_test::assert_tokens(&buf, {
830 use sval_test::Token::*;
831
832 &[TextBegin(Some(3)), TextFragment("abc"), TextEnd]
833 });
834 }
835
836 #[test]
837 #[cfg(feature = "alloc")]
838 fn stream_ref_text_buf_computed() {
839 let mut buf = TextBuf::new();
840 buf.push_fragment("123").unwrap();
841 buf.push_fragment("()").unwrap();
842 buf.push_fragment("data").unwrap();
843
844 let mut tokens = sval_test::TokenBuf::new();
845 buf.stream_ref(&mut tokens).unwrap();
846
847 assert_eq!(tokens.as_tokens(), {
848 use sval_test::Token::*;
849
850 &[
851 TextBegin(Some(9)),
852 TextFragmentComputed("123()data".to_owned()),
853 TextEnd,
854 ]
855 });
856 }
857
858 #[test]
859 fn stream_ref_text_buf_borrowed() {
860 let mut buf = TextBuf::new();
861 buf.push_fragment("123").unwrap();
862
863 let mut tokens = sval_test::TokenBuf::new();
864 buf.stream_ref(&mut tokens).unwrap();
865
866 assert_eq!(tokens.as_tokens(), {
867 use sval_test::Token::*;
868
869 &[TextBegin(Some(3)), TextFragment("123"), TextEnd]
870 });
871 }
872
873 #[test]
874 #[cfg(feature = "alloc")]
875 fn collect_text_buf_display() {
876 let buf = TextBuf::collect_display(true).unwrap();
877
878 assert_eq!("true", buf.as_str());
879 assert!(buf.as_borrowed_str().is_none());
880 }
881
882 #[test]
883 #[cfg(feature = "alloc")]
884 fn stream_text_buf_display() {
885 let mut buf = TextBuf::new();
886
887 buf.push_display(true).unwrap();
888 buf.push_display(false).unwrap();
889
890 assert_eq!("truefalse", buf.as_str());
891 assert!(buf.as_borrowed_str().is_none());
892 }
893
894 #[test]
895 #[cfg(feature = "alloc")]
896 fn stream_binary_buf_computed() {
897 let mut buf = BinaryBuf::new();
898 buf.push_fragment(b"abc").unwrap();
899 buf.push_fragment_computed(b"def").unwrap();
900
901 sval_test::assert_tokens(&buf, {
902 use sval_test::Token::*;
903
904 &[BinaryBegin(Some(6)), BinaryFragment(b"abcdef"), BinaryEnd]
905 });
906 }
907
908 #[test]
909 fn stream_ref_binary_buf_borrowed() {
910 let mut buf = BinaryBuf::new();
911 buf.push_fragment(b"abc").unwrap();
912
913 let mut tokens = sval_test::TokenBuf::new();
914 buf.stream_ref(&mut tokens).unwrap();
915
916 assert_eq!(tokens.as_tokens(), {
917 use sval_test::Token::*;
918
919 &[BinaryBegin(Some(3)), BinaryFragment(b"abc"), BinaryEnd]
920 });
921 }
922
923 #[test]
924 #[cfg(feature = "alloc")]
925 fn stream_ref_binary_buf_computed() {
926 let mut buf = BinaryBuf::new();
927 buf.push_fragment(b"abc").unwrap();
928 buf.push_fragment_computed(b"def").unwrap();
929
930 let mut tokens = sval_test::TokenBuf::new();
931 buf.stream_ref(&mut tokens).unwrap();
932
933 assert_eq!(tokens.as_tokens(), {
934 use sval_test::Token::*;
935
936 &[
937 BinaryBegin(Some(6)),
938 BinaryFragmentComputed(b"abcdef".to_vec()),
939 BinaryEnd,
940 ]
941 });
942 }
943}