Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sval_buffer-2.17.0/src/fragments.rs
Line
Count
Source
1
use crate::{
2
    std::fmt::{self, Write as _},
3
    Error,
4
};
5
6
#[cfg(feature = "alloc")]
7
use crate::std::{
8
    borrow::{Cow, ToOwned},
9
    mem,
10
};
11
12
/**
13
Buffer text fragments into a single contiguous string.
14
15
In no-std environments, this buffer only supports a single
16
borrowed text fragment. Other methods will fail.
17
*/
18
#[derive(Debug, Clone, PartialEq, Eq)]
19
pub struct TextBuf<'sval> {
20
    buf: FragmentBuf<'sval, str>,
21
}
22
23
impl<'sval> TextBuf<'sval> {
24
    /**
25
    Create a new empty text buffer.
26
    */
27
    #[inline(always)]
28
0
    pub fn new() -> Self {
29
0
        TextBuf {
30
0
            buf: FragmentBuf::new(""),
31
0
        }
32
0
    }
33
34
    /**
35
    Buffer a text value into a contiguous string.
36
    */
37
0
    pub fn collect(value: &'sval (impl sval::Value + ?Sized)) -> Result<Self, Error> {
38
0
        let mut collector = TextCollector {
39
0
            buf: TextBuf::new(),
40
0
            err: None,
41
0
        };
42
43
0
        value
44
0
            .stream(&mut collector)
45
0
            .map_err(|_| collector.err.unwrap())?;
46
47
0
        Ok(collector.buf)
48
0
    }
49
50
    /**
51
    Buffer a displayable value into a contiguous string.
52
    */
53
0
    pub fn collect_display(value: impl fmt::Display) -> Result<Self, Error> {
54
0
        let mut buf = TextBuf::new();
55
0
        buf.push_display(value)?;
56
57
0
        Ok(buf)
58
0
    }
59
60
    /**
61
    Clear the text buffer so it can be re-used.
62
    */
63
    #[inline(always)]
64
0
    pub fn clear(&mut self) {
65
0
        *self = Default::default();
66
0
    }
67
68
    /**
69
    Push a borrowed text fragment onto the buffer.
70
    */
71
    #[inline(always)]
72
0
    pub fn push_fragment(&mut self, fragment: &'sval str) -> Result<(), Error> {
73
0
        self.buf.push(fragment)
74
0
    }
75
76
    /**
77
    Push a computed text fragment onto the buffer.
78
79
    If the `std` feature of this library is enabled, this method will
80
    buffer the fragment. In no-std environments this method will fail.
81
    */
82
    #[inline(always)]
83
0
    pub fn push_fragment_computed(&mut self, fragment: &str) -> Result<(), Error> {
84
0
        self.buf.push_computed(fragment)
85
0
    }
86
87
    /**
88
    Push a displayable value onto the buffer.
89
90
    If the `std` feature of htis library is enabled, this method will
91
    buffer the fragment. In no-std environments this method will fail.
92
    */
93
0
    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
0
            fn write_str(&mut self, s: &str) -> fmt::Result {
101
0
                match self.buf.push_fragment_computed(s) {
102
0
                    Ok(()) => Ok(()),
103
0
                    Err(e) => {
104
0
                        self.err = Some(e);
105
0
                        Err(fmt::Error)
106
                    }
107
                }
108
0
            }
109
        }
110
111
0
        let mut writer = Writer {
112
0
            buf: self,
113
0
            err: None,
114
0
        };
115
116
0
        write!(&mut writer, "{}", value).map_err(|_| {
117
0
            writer
118
0
                .err
119
0
                .unwrap_or_else(|| Error::invalid_value("formatting failed"))
120
0
        })
121
0
    }
122
123
    /**
124
    Try get the contents of the buffer as a string borrowed for the `'sval` lifetime.
125
    */
126
    #[inline(always)]
127
0
    pub fn as_borrowed_str(&self) -> Option<&'sval str> {
128
0
        self.buf.as_borrowed_inner()
129
0
    }
130
131
    /**
132
    Get the contents of the buffer as a string.
133
    */
134
    #[inline(always)]
135
0
    pub fn as_str(&self) -> &str {
136
0
        self.buf.as_inner()
137
0
    }
138
139
    #[cfg(feature = "alloc")]
140
0
    pub(crate) fn into_owned_in_place(&mut self) -> &mut TextBuf<'static> {
141
0
        let TextBuf { ref mut buf } = self;
142
143
0
        crate::assert_static(buf.into_owned_in_place());
144
145
        // SAFETY: `self` no longer contains any data borrowed for `'sval`
146
0
        unsafe { mem::transmute::<&mut TextBuf<'sval>, &mut TextBuf<'static>>(self) }
147
0
    }
148
}
149
150
struct TextCollector<'a> {
151
    buf: TextBuf<'a>,
152
    err: Option<Error>,
153
}
154
155
impl<'a> TextCollector<'a> {
156
0
    fn try_catch(&mut self, f: impl FnOnce(&mut TextBuf<'a>) -> Result<(), Error>) -> sval::Result {
157
0
        match f(&mut self.buf) {
158
0
            Ok(()) => Ok(()),
159
0
            Err(e) => self.fail(e),
160
        }
161
0
    }
Unexecuted instantiation: <sval_buffer::fragments::TextCollector>::try_catch::<<sval_buffer::fragments::TextCollector as sval::stream::Stream>::text_fragment::{closure#0}>
Unexecuted instantiation: <sval_buffer::fragments::TextCollector>::try_catch::<<sval_buffer::fragments::TextCollector as sval::stream::Stream>::text_fragment_computed::{closure#0}>
162
163
0
    fn fail(&mut self, err: Error) -> sval::Result {
164
0
        self.err = Some(err);
165
0
        sval::error()
166
0
    }
167
}
168
169
impl<'a> sval::Stream<'a> for TextCollector<'a> {
170
0
    fn text_begin(&mut self, _: Option<usize>) -> sval::Result {
171
0
        Ok(())
172
0
    }
173
174
0
    fn text_fragment(&mut self, fragment: &'a str) -> sval::Result {
175
0
        self.try_catch(|buf| buf.push_fragment(fragment))
176
0
    }
177
178
0
    fn text_fragment_computed(&mut self, fragment: &str) -> sval::Result {
179
0
        self.try_catch(|buf| buf.push_fragment_computed(fragment))
180
0
    }
181
182
0
    fn text_end(&mut self) -> sval::Result {
183
0
        Ok(())
184
0
    }
185
186
0
    fn null(&mut self) -> sval::Result {
187
0
        self.fail(Error::unsupported("text", "null"))
188
0
    }
189
190
0
    fn bool(&mut self, _: bool) -> sval::Result {
191
0
        self.fail(Error::unsupported("text", "boolean"))
192
0
    }
193
194
0
    fn i64(&mut self, _: i64) -> sval::Result {
195
0
        self.fail(Error::unsupported("text", "integer"))
196
0
    }
197
198
0
    fn f64(&mut self, _: f64) -> sval::Result {
199
0
        self.fail(Error::unsupported("text", "floating point"))
200
0
    }
201
202
0
    fn seq_begin(&mut self, _: Option<usize>) -> sval::Result {
203
0
        self.fail(Error::unsupported("text", "sequence"))
204
0
    }
205
206
0
    fn seq_value_begin(&mut self) -> sval::Result {
207
0
        self.fail(Error::unsupported("text", "sequence"))
208
0
    }
209
210
0
    fn seq_value_end(&mut self) -> sval::Result {
211
0
        self.fail(Error::unsupported("text", "sequence"))
212
0
    }
213
214
0
    fn seq_end(&mut self) -> sval::Result {
215
0
        self.fail(Error::unsupported("text", "sequence"))
216
0
    }
217
}
218
219
impl<'sval> fmt::Write for TextBuf<'sval> {
220
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
221
0
        self.push_fragment_computed(s).map_err(|_| fmt::Error)
222
0
    }
223
}
224
225
impl<'sval> Default for TextBuf<'sval> {
226
    #[inline(always)]
227
0
    fn default() -> Self {
228
0
        TextBuf::new()
229
0
    }
230
}
231
232
impl<'sval> From<&'sval str> for TextBuf<'sval> {
233
    #[inline(always)]
234
0
    fn from(fragment: &'sval str) -> Self {
235
0
        TextBuf {
236
0
            buf: FragmentBuf::new(fragment),
237
0
        }
238
0
    }
239
}
240
241
impl<'sval> AsRef<str> for TextBuf<'sval> {
242
    #[inline(always)]
243
0
    fn as_ref(&self) -> &str {
244
0
        self.as_str()
245
0
    }
246
}
247
248
impl<'a> sval::Value for TextBuf<'a> {
249
0
    fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
250
0
        self.as_str().stream(stream)
251
0
    }
252
}
253
254
impl<'sval> sval_ref::ValueRef<'sval> for TextBuf<'sval> {
255
0
    fn stream_ref<S: sval::Stream<'sval> + ?Sized>(&self, stream: &mut S) -> sval::Result {
256
0
        match self.as_borrowed_str() {
257
0
            Some(v) => stream.value(v),
258
            None => {
259
0
                let v = self.as_str();
260
261
0
                stream.text_begin(Some(v.len()))?;
262
0
                stream.text_fragment_computed(v)?;
263
0
                stream.text_end()
264
            }
265
        }
266
0
    }
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<dyn sval_dynamic::stream::Stream>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::tag::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_f32::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_f64::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_bool::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_i128::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_text::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_u128::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_binary::Extract>
Unexecuted instantiation: <sval_buffer::fragments::TextBuf as sval_ref::ValueRef>::stream_ref::<_>
267
}
268
269
/**
270
Buffer binary fragments into a single contiguous slice.
271
272
In no-std environments, this buffer only supports a single
273
borrowed binary fragment. Other methods will fail.
274
*/
275
#[derive(Debug, Clone, PartialEq, Eq)]
276
pub struct BinaryBuf<'sval> {
277
    buf: FragmentBuf<'sval, [u8]>,
278
}
279
280
impl<'sval> BinaryBuf<'sval> {
281
    /**
282
    Create a new empty binary buffer.
283
    */
284
    #[inline(always)]
285
0
    pub fn new() -> Self {
286
0
        BinaryBuf {
287
0
            buf: FragmentBuf::new(&[]),
288
0
        }
289
0
    }
290
291
    /**
292
    Buffer a binary value into a contiguous slice.
293
    */
294
0
    pub fn collect(value: &'sval (impl sval::Value + ?Sized)) -> Result<Self, Error> {
295
0
        let mut collector = BinaryCollector {
296
0
            buf: BinaryBuf::new(),
297
0
            err: None,
298
0
        };
299
300
0
        value
301
0
            .stream(&mut collector)
302
0
            .map_err(|_| collector.err.unwrap())?;
303
304
0
        Ok(collector.buf)
305
0
    }
306
307
    /**
308
    Clear the binary buffer so it can be re-used.
309
    */
310
    #[inline(always)]
311
0
    pub fn clear(&mut self) {
312
0
        *self = Default::default();
313
0
    }
314
315
    /**
316
    Push a borrowed binary fragment onto the buffer.
317
    */
318
    #[inline(always)]
319
0
    pub fn push_fragment(&mut self, fragment: &'sval [u8]) -> Result<(), Error> {
320
0
        self.buf.push(fragment)
321
0
    }
322
323
    /**
324
    Push a computed binary fragment onto the buffer.
325
326
    If the `std` feature of this library is enabled, this method will
327
    buffer the fragment. In no-std environments this method will fail.
328
    */
329
    #[inline(always)]
330
0
    pub fn push_fragment_computed(&mut self, fragment: &[u8]) -> Result<(), Error> {
331
0
        self.buf.push_computed(fragment)
332
0
    }
333
334
    /**
335
    Try get the contents of the buffer as a slice borrowed for the `'sval` lifetime.
336
    */
337
    #[inline(always)]
338
0
    pub fn as_borrowed_slice(&self) -> Option<&'sval [u8]> {
339
0
        self.buf.as_borrowed_inner()
340
0
    }
341
342
    /**
343
    Get the contents of the buffer as a slice.
344
    */
345
    #[inline(always)]
346
0
    pub fn as_slice(&self) -> &[u8] {
347
0
        self.buf.as_inner()
348
0
    }
349
350
    #[cfg(feature = "alloc")]
351
0
    pub(crate) fn into_owned_in_place(&mut self) -> &mut BinaryBuf<'static> {
352
0
        let BinaryBuf { ref mut buf } = self;
353
354
0
        crate::assert_static(buf.into_owned_in_place());
355
356
        // SAFETY: `self` no longer contains any data borrowed for `'sval`
357
0
        unsafe { mem::transmute::<&mut BinaryBuf<'sval>, &mut BinaryBuf<'static>>(self) }
358
0
    }
359
}
360
361
struct BinaryCollector<'a> {
362
    buf: BinaryBuf<'a>,
363
    err: Option<Error>,
364
}
365
366
impl<'a> BinaryCollector<'a> {
367
0
    fn try_catch(
368
0
        &mut self,
369
0
        f: impl FnOnce(&mut BinaryBuf<'a>) -> Result<(), Error>,
370
0
    ) -> sval::Result {
371
0
        match f(&mut self.buf) {
372
0
            Ok(()) => Ok(()),
373
0
            Err(e) => self.fail(e),
374
        }
375
0
    }
Unexecuted instantiation: <sval_buffer::fragments::BinaryCollector>::try_catch::<<sval_buffer::fragments::BinaryCollector as sval::stream::Stream>::binary_fragment::{closure#0}>
Unexecuted instantiation: <sval_buffer::fragments::BinaryCollector>::try_catch::<<sval_buffer::fragments::BinaryCollector as sval::stream::Stream>::binary_fragment_computed::{closure#0}>
Unexecuted instantiation: <sval_buffer::fragments::BinaryCollector>::try_catch::<<sval_buffer::fragments::BinaryCollector as sval::stream::Stream>::u8::{closure#0}>
376
377
0
    fn fail(&mut self, err: Error) -> sval::Result {
378
0
        self.err = Some(err);
379
0
        sval::error()
380
0
    }
381
}
382
383
impl<'a> sval::Stream<'a> for BinaryCollector<'a> {
384
0
    fn binary_begin(&mut self, _: Option<usize>) -> sval::Result {
385
0
        Ok(())
386
0
    }
387
388
0
    fn binary_fragment(&mut self, fragment: &'a [u8]) -> sval::Result {
389
0
        self.try_catch(|buf| buf.push_fragment(fragment))
390
0
    }
391
392
0
    fn binary_fragment_computed(&mut self, fragment: &[u8]) -> sval::Result {
393
0
        self.try_catch(|buf| buf.push_fragment_computed(fragment))
394
0
    }
395
396
0
    fn binary_end(&mut self) -> sval::Result {
397
0
        Ok(())
398
0
    }
399
400
0
    fn text_begin(&mut self, _: Option<usize>) -> sval::Result {
401
0
        self.fail(Error::unsupported("binary", "text"))
402
0
    }
403
404
0
    fn text_fragment_computed(&mut self, _: &str) -> sval::Result {
405
0
        self.fail(Error::unsupported("binary", "text"))
406
0
    }
407
408
0
    fn text_end(&mut self) -> sval::Result {
409
0
        self.fail(Error::unsupported("binary", "text"))
410
0
    }
411
412
0
    fn null(&mut self) -> sval::Result {
413
0
        self.fail(Error::unsupported("binary", "null"))
414
0
    }
415
416
0
    fn bool(&mut self, _: bool) -> sval::Result {
417
0
        self.fail(Error::unsupported("binary", "boolean"))
418
0
    }
419
420
0
    fn u8(&mut self, value: u8) -> sval::Result {
421
0
        self.try_catch(|buf| buf.push_fragment_computed(&[value]))
422
0
    }
423
424
0
    fn i64(&mut self, _: i64) -> sval::Result {
425
0
        self.fail(Error::unsupported("binary", "integer"))
426
0
    }
427
428
0
    fn f64(&mut self, _: f64) -> sval::Result {
429
0
        self.fail(Error::unsupported("binary", "floating point"))
430
0
    }
431
432
0
    fn map_begin(&mut self, _: Option<usize>) -> sval::Result {
433
0
        self.fail(Error::unsupported("binary", "map"))
434
0
    }
435
436
0
    fn seq_begin(&mut self, _: Option<usize>) -> sval::Result {
437
0
        Ok(())
438
0
    }
439
440
0
    fn seq_value_begin(&mut self) -> sval::Result {
441
0
        Ok(())
442
0
    }
443
444
0
    fn seq_value_end(&mut self) -> sval::Result {
445
0
        Ok(())
446
0
    }
447
448
0
    fn seq_end(&mut self) -> sval::Result {
449
0
        Ok(())
450
0
    }
451
}
452
453
impl<'sval> Default for BinaryBuf<'sval> {
454
    #[inline(always)]
455
0
    fn default() -> Self {
456
0
        BinaryBuf::new()
457
0
    }
458
}
459
460
impl<'sval> From<&'sval [u8]> for BinaryBuf<'sval> {
461
    #[inline(always)]
462
0
    fn from(fragment: &'sval [u8]) -> Self {
463
0
        BinaryBuf {
464
0
            buf: FragmentBuf::new(fragment),
465
0
        }
466
0
    }
467
}
468
469
impl<'sval, const N: usize> From<&'sval [u8; N]> for BinaryBuf<'sval> {
470
0
    fn from(fragment: &'sval [u8; N]) -> Self {
471
0
        BinaryBuf {
472
0
            buf: FragmentBuf::new(fragment),
473
0
        }
474
0
    }
475
}
476
477
impl<'sval> AsRef<[u8]> for BinaryBuf<'sval> {
478
    #[inline(always)]
479
0
    fn as_ref(&self) -> &[u8] {
480
0
        self.as_slice()
481
0
    }
482
}
483
484
impl<'a> sval::Value for BinaryBuf<'a> {
485
0
    fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
486
0
        sval::BinarySlice::new(self.as_slice()).stream(stream)
487
0
    }
488
}
489
490
impl<'sval> sval_ref::ValueRef<'sval> for BinaryBuf<'sval> {
491
0
    fn stream_ref<S: sval::Stream<'sval> + ?Sized>(&self, stream: &mut S) -> sval::Result {
492
0
        match self.as_borrowed_slice() {
493
0
            Some(v) => stream.value(sval::BinarySlice::new(v)),
494
0
            None => stream.value_computed(sval::BinarySlice::new(self.as_slice())),
495
        }
496
0
    }
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<dyn sval_dynamic::stream::Stream>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::tag::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_f32::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_f64::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_bool::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_i128::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_text::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_u128::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<sval::value::default_value::to_binary::Extract>
Unexecuted instantiation: <sval_buffer::fragments::BinaryBuf as sval_ref::ValueRef>::stream_ref::<_>
497
}
498
499
#[cfg(not(feature = "alloc"))]
500
trait 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")]
510
trait Fragment: ToOwned {
511
    #[inline(always)]
512
0
    fn to_fragment<'sval>(&'sval self) -> Cow<'sval, Self> {
513
0
        Cow::Borrowed(self)
514
0
    }
Unexecuted instantiation: <str as sval_buffer::fragments::Fragment>::to_fragment
Unexecuted instantiation: <[u8] as sval_buffer::fragments::Fragment>::to_fragment
Unexecuted instantiation: <str as sval_buffer::fragments::Fragment>::to_fragment
515
516
    fn extend(buf: &mut Cow<Self>, fragment: &Self);
517
518
    fn can_replace(&self) -> bool;
519
520
0
    fn into_owned_in_place<'a, 'sval>(buf: &'a mut Cow<'sval, Self>) -> &'a mut Cow<'static, Self> {
521
0
        if let Cow::Borrowed(v) = buf {
522
0
            *buf = Cow::Owned(v.to_owned());
523
0
        }
524
525
        // SAFETY: `self` no longer contains any data borrowed for `'sval`
526
0
        unsafe { mem::transmute::<&mut Cow<'_, Self>, &mut Cow<'static, Self>>(buf) }
527
0
    }
Unexecuted instantiation: <[u8] as sval_buffer::fragments::Fragment>::into_owned_in_place
Unexecuted instantiation: <str as sval_buffer::fragments::Fragment>::into_owned_in_place
528
}
529
530
impl Fragment for str {
531
    #[cfg(feature = "alloc")]
532
    #[inline(always)]
533
0
    fn extend(buf: &mut Cow<Self>, fragment: &Self) {
534
0
        buf.to_mut().push_str(fragment);
535
0
    }
536
537
0
    fn can_replace(&self) -> bool {
538
0
        self.len() == 0
539
0
    }
540
}
541
542
impl Fragment for [u8] {
543
    #[cfg(feature = "alloc")]
544
    #[inline(always)]
545
0
    fn extend(buf: &mut Cow<Self>, fragment: &Self) {
546
0
        buf.to_mut().extend(fragment);
547
0
    }
548
549
0
    fn can_replace(&self) -> bool {
550
0
        self.len() == 0
551
0
    }
552
}
553
554
struct 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"))]
562
impl<'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")]
569
impl<'sval, T: ?Sized + Fragment> Clone for FragmentBuf<'sval, T>
570
where
571
    T::Owned: Clone,
572
{
573
0
    fn clone(&self) -> Self {
574
0
        FragmentBuf {
575
0
            value: self.value.clone(),
576
0
        }
577
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]> as core::clone::Clone>::clone
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str> as core::clone::Clone>::clone
578
}
579
580
#[cfg(not(feature = "alloc"))]
581
impl<'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")]
588
impl<'sval, T: ?Sized + Fragment + fmt::Debug> fmt::Debug for FragmentBuf<'sval, T>
589
where
590
    T::Owned: fmt::Debug,
591
{
592
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
593
0
        self.value.fmt(f)
594
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]> as core::fmt::Debug>::fmt
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str> as core::fmt::Debug>::fmt
595
}
596
597
#[cfg(not(feature = "alloc"))]
598
impl<'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")]
605
impl<'sval, T: ?Sized + Fragment + PartialEq> PartialEq for FragmentBuf<'sval, T>
606
where
607
    T::Owned: PartialEq,
608
{
609
0
    fn eq(&self, other: &Self) -> bool {
610
0
        self.value == other.value
611
0
    }
612
}
613
614
#[cfg(not(feature = "alloc"))]
615
impl<'sval, T: ?Sized + Fragment + PartialEq> Eq for FragmentBuf<'sval, T> {}
616
617
#[cfg(feature = "alloc")]
618
impl<'sval, T: ?Sized + Fragment + Eq> Eq for FragmentBuf<'sval, T> where T::Owned: Eq {}
619
620
impl<'sval, T: ?Sized + Fragment> FragmentBuf<'sval, T> {
621
    #[inline(always)]
622
0
    fn new(value: &'sval T) -> Self {
623
0
        FragmentBuf {
624
0
            value: value.to_fragment(),
625
0
        }
626
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::new
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::new
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::new
627
628
    #[inline(always)]
629
0
    fn push(&mut self, fragment: &'sval T) -> Result<(), Error> {
630
0
        if self.value.can_replace() {
631
0
            self.value = fragment.to_fragment();
632
633
0
            Ok(())
634
        } else {
635
0
            self.push_computed(fragment)
636
        }
637
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::push
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::push
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::push
638
639
    #[inline(always)]
640
0
    fn push_computed(&mut self, fragment: &T) -> Result<(), Error> {
641
        #[cfg(feature = "alloc")]
642
        {
643
0
            Fragment::extend(&mut self.value, fragment);
644
645
0
            Ok(())
646
        }
647
648
        #[cfg(not(feature = "alloc"))]
649
        {
650
            let _ = fragment;
651
            Err(Error::no_alloc("computed fragment"))
652
        }
653
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::push_computed
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::push_computed
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::push_computed
654
655
    #[inline(always)]
656
0
    fn as_borrowed_inner(&self) -> Option<&'sval T> {
657
        #[cfg(feature = "alloc")]
658
        {
659
0
            match self.value {
660
0
                Cow::Borrowed(value) => Some(value),
661
0
                Cow::Owned(_) => None,
662
            }
663
        }
664
665
        #[cfg(not(feature = "alloc"))]
666
        {
667
            Some(self.value)
668
        }
669
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::as_borrowed_inner
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::as_borrowed_inner
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<_>>::as_borrowed_inner
670
671
    #[inline(always)]
672
0
    fn as_inner(&self) -> &T {
673
        #[cfg(feature = "alloc")]
674
        {
675
0
            &*self.value
676
        }
677
678
        #[cfg(not(feature = "alloc"))]
679
        {
680
            self.value
681
        }
682
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::as_inner
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::as_inner
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<_>>::as_inner
683
684
    #[cfg(feature = "alloc")]
685
0
    pub(crate) fn into_owned_in_place(&mut self) -> &mut FragmentBuf<'static, T> {
686
0
        crate::assert_static(Fragment::into_owned_in_place(&mut self.value));
687
688
        // SAFETY: `self` no longer contains any data borrowed for `'sval`
689
0
        unsafe { mem::transmute::<&mut FragmentBuf<'sval, T>, &mut FragmentBuf<'static, T>>(self) }
690
0
    }
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<[u8]>>::into_owned_in_place
Unexecuted instantiation: <sval_buffer::fragments::FragmentBuf<str>>::into_owned_in_place
691
}
692
693
#[cfg(test)]
694
mod 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
}