Coverage Report

Created: 2025-05-08 06:13

/rust/registry/src/index.crates.io-6f17d22bba15001f/tendril-0.4.3/src/tendril.rs
Line
Count
Source (jump to first uncovered line)
1
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
4
// option. This file may not be copied, modified, or distributed
5
// except according to those terms.
6
7
use std::borrow::Borrow;
8
use std::cell::{Cell, UnsafeCell};
9
use std::cmp::Ordering;
10
use std::default::Default;
11
use std::fmt as strfmt;
12
use std::iter::FromIterator;
13
use std::marker::PhantomData;
14
use std::num::NonZeroUsize;
15
use std::ops::{Deref, DerefMut};
16
use std::sync::atomic::Ordering as AtomicOrdering;
17
use std::sync::atomic::{self, AtomicUsize};
18
use std::{hash, io, mem, ptr, str, u32};
19
20
#[cfg(feature = "encoding")]
21
use encoding::{self, DecoderTrap, EncoderTrap, EncodingRef};
22
23
use buf32::{self, Buf32};
24
use fmt::imp::Fixup;
25
use fmt::{self, Slice};
26
use util::{copy_and_advance, copy_lifetime, copy_lifetime_mut, unsafe_slice, unsafe_slice_mut};
27
use OFLOW;
28
29
const MAX_INLINE_LEN: usize = 8;
30
const MAX_INLINE_TAG: usize = 0xF;
31
const EMPTY_TAG: usize = 0xF;
32
33
#[inline(always)]
34
112M
fn inline_tag(len: u32) -> NonZeroUsize {
35
112M
    debug_assert!(len <= MAX_INLINE_LEN as u32);
36
112M
    unsafe { NonZeroUsize::new_unchecked(if len == 0 { EMPTY_TAG } else { len as usize }) }
37
112M
}
38
39
/// The multithreadedness of a tendril.
40
///
41
/// Exactly two types implement this trait:
42
///
43
/// - `Atomic`: use this in your tendril and you will have a `Send` tendril which works
44
///   across threads; this is akin to `Arc`.
45
///
46
/// - `NonAtomic`: use this in your tendril and you will have a tendril which is neither
47
///   `Send` nor `Sync` but should be a tad faster; this is akin to `Rc`.
48
///
49
/// The layout of this trait is also mandated to be that of a `usize`,
50
/// for it is used for reference counting.
51
pub unsafe trait Atomicity: 'static {
52
    #[doc(hidden)]
53
    fn new() -> Self;
54
55
    #[doc(hidden)]
56
    fn increment(&self) -> usize;
57
58
    #[doc(hidden)]
59
    fn decrement(&self) -> usize;
60
61
    #[doc(hidden)]
62
    fn fence_acquire();
63
}
64
65
/// A marker of a non-atomic tendril.
66
///
67
/// This is the default for the second type parameter of a `Tendril`
68
/// and so doesn't typically need to be written.
69
///
70
/// This is akin to using `Rc` for reference counting.
71
#[repr(C)]
72
pub struct NonAtomic(Cell<usize>);
73
74
unsafe impl Atomicity for NonAtomic {
75
    #[inline]
76
1.33M
    fn new() -> Self {
77
1.33M
        NonAtomic(Cell::new(1))
78
1.33M
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::new
Line
Count
Source
76
50.6k
    fn new() -> Self {
77
50.6k
        NonAtomic(Cell::new(1))
78
50.6k
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::new
Line
Count
Source
76
1.17M
    fn new() -> Self {
77
1.17M
        NonAtomic(Cell::new(1))
78
1.17M
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::new
Line
Count
Source
76
105k
    fn new() -> Self {
77
105k
        NonAtomic(Cell::new(1))
78
105k
    }
Unexecuted instantiation: <tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::new
79
80
    #[inline]
81
1.47M
    fn increment(&self) -> usize {
82
1.47M
        let value = self.0.get();
83
1.47M
        self.0.set(value.checked_add(1).expect(OFLOW));
84
1.47M
        value
85
1.47M
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::increment
Line
Count
Source
81
832k
    fn increment(&self) -> usize {
82
832k
        let value = self.0.get();
83
832k
        self.0.set(value.checked_add(1).expect(OFLOW));
84
832k
        value
85
832k
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::increment
Line
Count
Source
81
638k
    fn increment(&self) -> usize {
82
638k
        let value = self.0.get();
83
638k
        self.0.set(value.checked_add(1).expect(OFLOW));
84
638k
        value
85
638k
    }
Unexecuted instantiation: <tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::increment
86
87
    #[inline]
88
1.92M
    fn decrement(&self) -> usize {
89
1.92M
        let value = self.0.get();
90
1.92M
        self.0.set(value - 1);
91
1.92M
        value
92
1.92M
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::decrement
Line
Count
Source
88
16.5k
    fn decrement(&self) -> usize {
89
16.5k
        let value = self.0.get();
90
16.5k
        self.0.set(value - 1);
91
16.5k
        value
92
16.5k
    }
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::decrement
Line
Count
Source
88
1.90M
    fn decrement(&self) -> usize {
89
1.90M
        let value = self.0.get();
90
1.90M
        self.0.set(value - 1);
91
1.90M
        value
92
1.90M
    }
Unexecuted instantiation: <tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::decrement
93
94
    #[inline]
95
452k
    fn fence_acquire() {}
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::fence_acquire
Line
Count
Source
95
15.4k
    fn fence_acquire() {}
<tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::fence_acquire
Line
Count
Source
95
437k
    fn fence_acquire() {}
Unexecuted instantiation: <tendril::tendril::NonAtomic as tendril::tendril::Atomicity>::fence_acquire
96
}
97
98
/// A marker of an atomic (and hence concurrent) tendril.
99
///
100
/// This is used as the second, optional type parameter of a `Tendril`;
101
/// `Tendril<F, Atomic>` thus implements`Send`.
102
///
103
/// This is akin to using `Arc` for reference counting.
104
pub struct Atomic(AtomicUsize);
105
106
unsafe impl Atomicity for Atomic {
107
    #[inline]
108
0
    fn new() -> Self {
109
0
        Atomic(AtomicUsize::new(1))
110
0
    }
111
112
    #[inline]
113
0
    fn increment(&self) -> usize {
114
0
        // Relaxed is OK because we have a reference already.
115
0
        self.0.fetch_add(1, AtomicOrdering::Relaxed)
116
0
    }
117
118
    #[inline]
119
0
    fn decrement(&self) -> usize {
120
0
        self.0.fetch_sub(1, AtomicOrdering::Release)
121
0
    }
122
123
    #[inline]
124
0
    fn fence_acquire() {
125
0
        atomic::fence(AtomicOrdering::Acquire);
126
0
    }
127
}
128
129
#[repr(C)] // Preserve field order for cross-atomicity transmutes
130
struct Header<A: Atomicity> {
131
    refcount: A,
132
    cap: u32,
133
}
134
135
impl<A> Header<A>
136
where
137
    A: Atomicity,
138
{
139
    #[inline(always)]
140
1.33M
    unsafe fn new() -> Header<A> {
141
1.33M
        Header {
142
1.33M
            refcount: A::new(),
143
1.33M
            cap: 0,
144
1.33M
        }
145
1.33M
    }
<tendril::tendril::Header<tendril::tendril::NonAtomic>>::new
Line
Count
Source
140
50.6k
    unsafe fn new() -> Header<A> {
141
50.6k
        Header {
142
50.6k
            refcount: A::new(),
143
50.6k
            cap: 0,
144
50.6k
        }
145
50.6k
    }
<tendril::tendril::Header<tendril::tendril::NonAtomic>>::new
Line
Count
Source
140
1.17M
    unsafe fn new() -> Header<A> {
141
1.17M
        Header {
142
1.17M
            refcount: A::new(),
143
1.17M
            cap: 0,
144
1.17M
        }
145
1.17M
    }
<tendril::tendril::Header<tendril::tendril::NonAtomic>>::new
Line
Count
Source
140
105k
    unsafe fn new() -> Header<A> {
141
105k
        Header {
142
105k
            refcount: A::new(),
143
105k
            cap: 0,
144
105k
        }
145
105k
    }
Unexecuted instantiation: <tendril::tendril::Header<_>>::new
146
}
147
148
/// Errors that can occur when slicing a `Tendril`.
149
#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq)]
150
pub enum SubtendrilError {
151
    OutOfBounds,
152
    ValidationFailed,
153
}
154
155
/// Compact string type for zero-copy parsing.
156
///
157
/// `Tendril`s have the semantics of owned strings, but are sometimes views
158
/// into shared buffers. When you mutate a `Tendril`, an owned copy is made
159
/// if necessary. Further mutations occur in-place until the string becomes
160
/// shared, e.g. with `clone()` or `subtendril()`.
161
///
162
/// Buffer sharing is accomplished through thread-local (non-atomic) reference
163
/// counting, which has very low overhead. The Rust type system will prevent
164
/// you at compile time from sending a `Tendril` between threads. We plan to
165
/// relax this restriction in the future; see `README.md`.
166
///
167
/// Whereas `String` allocates in the heap for any non-empty string, `Tendril`
168
/// can store small strings (up to 8 bytes) in-line, without a heap allocation.
169
/// `Tendril` is also smaller than `String` on 64-bit platforms — 16 bytes
170
/// versus 24.
171
///
172
/// The type parameter `F` specifies the format of the tendril, for example
173
/// UTF-8 text or uninterpreted bytes. The parameter will be instantiated
174
/// with one of the marker types from `tendril::fmt`. See the `StrTendril`
175
/// and `ByteTendril` type aliases for two examples.
176
///
177
/// The type parameter `A` indicates the atomicity of the tendril; it is by
178
/// default `NonAtomic`, but can be specified as `Atomic` to get a tendril
179
/// which implements `Send` (viz. a thread-safe tendril).
180
///
181
/// The maximum length of a `Tendril` is 4 GB. The library will panic if
182
/// you attempt to go over the limit.
183
#[repr(C)]
184
pub struct Tendril<F, A = NonAtomic>
185
where
186
    F: fmt::Format,
187
    A: Atomicity,
188
{
189
    ptr: Cell<NonZeroUsize>,
190
    buf: UnsafeCell<Buffer>,
191
    marker: PhantomData<*mut F>,
192
    refcount_marker: PhantomData<A>,
193
}
194
195
#[repr(C)]
196
union Buffer {
197
    heap: Heap,
198
    inline: [u8; 8],
199
}
200
201
#[derive(Copy, Clone)]
202
#[repr(C)]
203
struct Heap {
204
    len: u32,
205
    aux: u32,
206
}
207
208
unsafe impl<F, A> Send for Tendril<F, A>
209
where
210
    F: fmt::Format,
211
    A: Atomicity + Sync,
212
{
213
}
214
215
/// `Tendril` for storing native Rust strings.
216
pub type StrTendril = Tendril<fmt::UTF8>;
217
218
/// `Tendril` for storing binary data.
219
pub type ByteTendril = Tendril<fmt::Bytes>;
220
221
impl<F, A> Clone for Tendril<F, A>
222
where
223
    F: fmt::Format,
224
    A: Atomicity,
225
{
226
    #[inline]
227
1.37M
    fn clone(&self) -> Tendril<F, A> {
228
1.37M
        unsafe {
229
1.37M
            if self.ptr.get().get() > MAX_INLINE_TAG {
230
30.6k
                self.make_buf_shared();
231
30.6k
                self.incref();
232
1.34M
            }
233
234
1.37M
            ptr::read(self)
235
1.37M
        }
236
1.37M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8> as core::clone::Clone>::clone
Line
Count
Source
227
1.37M
    fn clone(&self) -> Tendril<F, A> {
228
1.37M
        unsafe {
229
1.37M
            if self.ptr.get().get() > MAX_INLINE_TAG {
230
30.6k
                self.make_buf_shared();
231
30.6k
                self.incref();
232
1.34M
            }
233
234
1.37M
            ptr::read(self)
235
1.37M
        }
236
1.37M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::clone::Clone>::clone
237
}
238
239
impl<F, A> Drop for Tendril<F, A>
240
where
241
    F: fmt::Format,
242
    A: Atomicity,
243
{
244
    #[inline]
245
116M
    fn drop(&mut self) {
246
116M
        unsafe {
247
116M
            let p = self.ptr.get().get();
248
116M
            if p <= MAX_INLINE_TAG {
249
114M
                return;
250
2.80M
            }
251
2.80M
252
2.80M
            let (buf, shared, _) = self.assume_buf();
253
2.80M
            if shared {
254
1.92M
                let header = self.header();
255
1.92M
                if (*header).refcount.decrement() == 1 {
256
452k
                    A::fence_acquire();
257
452k
                    buf.destroy();
258
1.47M
                }
259
882k
            } else {
260
882k
                buf.destroy();
261
882k
            }
262
        }
263
116M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes> as core::ops::drop::Drop>::drop
Line
Count
Source
245
167k
    fn drop(&mut self) {
246
167k
        unsafe {
247
167k
            let p = self.ptr.get().get();
248
167k
            if p <= MAX_INLINE_TAG {
249
135k
                return;
250
31.8k
            }
251
31.8k
252
31.8k
            let (buf, shared, _) = self.assume_buf();
253
31.8k
            if shared {
254
16.5k
                let header = self.header();
255
16.5k
                if (*header).refcount.decrement() == 1 {
256
15.4k
                    A::fence_acquire();
257
15.4k
                    buf.destroy();
258
15.4k
                }
259
15.3k
            } else {
260
15.3k
                buf.destroy();
261
15.3k
            }
262
        }
263
167k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8> as core::ops::drop::Drop>::drop
Line
Count
Source
245
116M
    fn drop(&mut self) {
246
116M
        unsafe {
247
116M
            let p = self.ptr.get().get();
248
116M
            if p <= MAX_INLINE_TAG {
249
113M
                return;
250
2.77M
            }
251
2.77M
252
2.77M
            let (buf, shared, _) = self.assume_buf();
253
2.77M
            if shared {
254
1.90M
                let header = self.header();
255
1.90M
                if (*header).refcount.decrement() == 1 {
256
437k
                    A::fence_acquire();
257
437k
                    buf.destroy();
258
1.46M
                }
259
867k
            } else {
260
867k
                buf.destroy();
261
867k
            }
262
        }
263
116M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::ops::drop::Drop>::drop
264
}
265
266
macro_rules! from_iter_method {
267
    ($ty:ty) => {
268
        #[inline]
269
0
        fn from_iter<I>(iterable: I) -> Self
270
0
        where
271
0
            I: IntoIterator<Item = $ty>,
272
0
        {
273
0
            let mut output = Self::new();
274
0
            output.extend(iterable);
275
0
            output
276
0
        }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8, _> as core::iter::traits::collect::FromIterator<char>>::from_iter::<_>
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::Bytes, _> as core::iter::traits::collect::FromIterator<u8>>::from_iter::<_>
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::Bytes, _> as core::iter::traits::collect::FromIterator<&u8>>::from_iter::<_>
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8, _> as core::iter::traits::collect::FromIterator<&str>>::from_iter::<_>
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::Bytes, _> as core::iter::traits::collect::FromIterator<&[u8]>>::from_iter::<_>
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::iter::traits::collect::FromIterator<&tendril::tendril::Tendril<_, _>>>::from_iter::<_>
277
    };
278
}
279
280
impl<A> Extend<char> for Tendril<fmt::UTF8, A>
281
where
282
    A: Atomicity,
283
{
284
    #[inline]
285
0
    fn extend<I>(&mut self, iterable: I)
286
0
    where
287
0
        I: IntoIterator<Item = char>,
288
0
    {
289
0
        let iterator = iterable.into_iter();
290
0
        self.force_reserve(iterator.size_hint().0 as u32);
291
0
        for c in iterator {
292
0
            self.push_char(c);
293
0
        }
294
0
    }
295
}
296
297
impl<A> FromIterator<char> for Tendril<fmt::UTF8, A>
298
where
299
    A: Atomicity,
300
{
301
    from_iter_method!(char);
302
}
303
304
impl<A> Extend<u8> for Tendril<fmt::Bytes, A>
305
where
306
    A: Atomicity,
307
{
308
    #[inline]
309
0
    fn extend<I>(&mut self, iterable: I)
310
0
    where
311
0
        I: IntoIterator<Item = u8>,
312
0
    {
313
0
        let iterator = iterable.into_iter();
314
0
        self.force_reserve(iterator.size_hint().0 as u32);
315
0
        for b in iterator {
316
0
            self.push_slice(&[b]);
317
0
        }
318
0
    }
319
}
320
321
impl<A> FromIterator<u8> for Tendril<fmt::Bytes, A>
322
where
323
    A: Atomicity,
324
{
325
    from_iter_method!(u8);
326
}
327
328
impl<'a, A> Extend<&'a u8> for Tendril<fmt::Bytes, A>
329
where
330
    A: Atomicity,
331
{
332
    #[inline]
333
0
    fn extend<I>(&mut self, iterable: I)
334
0
    where
335
0
        I: IntoIterator<Item = &'a u8>,
336
0
    {
337
0
        let iterator = iterable.into_iter();
338
0
        self.force_reserve(iterator.size_hint().0 as u32);
339
0
        for &b in iterator {
340
0
            self.push_slice(&[b]);
341
0
        }
342
0
    }
343
}
344
345
impl<'a, A> FromIterator<&'a u8> for Tendril<fmt::Bytes, A>
346
where
347
    A: Atomicity,
348
{
349
    from_iter_method!(&'a u8);
350
}
351
352
impl<'a, A> Extend<&'a str> for Tendril<fmt::UTF8, A>
353
where
354
    A: Atomicity,
355
{
356
    #[inline]
357
0
    fn extend<I>(&mut self, iterable: I)
358
0
    where
359
0
        I: IntoIterator<Item = &'a str>,
360
0
    {
361
0
        for s in iterable {
362
0
            self.push_slice(s);
363
0
        }
364
0
    }
365
}
366
367
impl<'a, A> FromIterator<&'a str> for Tendril<fmt::UTF8, A>
368
where
369
    A: Atomicity,
370
{
371
    from_iter_method!(&'a str);
372
}
373
374
impl<'a, A> Extend<&'a [u8]> for Tendril<fmt::Bytes, A>
375
where
376
    A: Atomicity,
377
{
378
    #[inline]
379
0
    fn extend<I>(&mut self, iterable: I)
380
0
    where
381
0
        I: IntoIterator<Item = &'a [u8]>,
382
0
    {
383
0
        for s in iterable {
384
0
            self.push_slice(s);
385
0
        }
386
0
    }
387
}
388
389
impl<'a, A> FromIterator<&'a [u8]> for Tendril<fmt::Bytes, A>
390
where
391
    A: Atomicity,
392
{
393
    from_iter_method!(&'a [u8]);
394
}
395
396
impl<'a, F, A> Extend<&'a Tendril<F, A>> for Tendril<F, A>
397
where
398
    F: fmt::Format + 'a,
399
    A: Atomicity,
400
{
401
    #[inline]
402
0
    fn extend<I>(&mut self, iterable: I)
403
0
    where
404
0
        I: IntoIterator<Item = &'a Tendril<F, A>>,
405
0
    {
406
0
        for t in iterable {
407
0
            self.push_tendril(t);
408
0
        }
409
0
    }
410
}
411
412
impl<'a, F, A> FromIterator<&'a Tendril<F, A>> for Tendril<F, A>
413
where
414
    F: fmt::Format + 'a,
415
    A: Atomicity,
416
{
417
    from_iter_method!(&'a Tendril<F, A>);
418
}
419
420
impl<F, A> Deref for Tendril<F, A>
421
where
422
    F: fmt::SliceFormat,
423
    A: Atomicity,
424
{
425
    type Target = F::Slice;
426
427
    #[inline]
428
274M
    fn deref(&self) -> &F::Slice {
429
274M
        unsafe { F::Slice::from_bytes(self.as_byte_slice()) }
430
274M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes> as core::ops::deref::Deref>::deref
Line
Count
Source
428
84.2M
    fn deref(&self) -> &F::Slice {
429
84.2M
        unsafe { F::Slice::from_bytes(self.as_byte_slice()) }
430
84.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8> as core::ops::deref::Deref>::deref
Line
Count
Source
428
189M
    fn deref(&self) -> &F::Slice {
429
189M
        unsafe { F::Slice::from_bytes(self.as_byte_slice()) }
430
189M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::ops::deref::Deref>::deref
431
}
432
433
impl<F, A> DerefMut for Tendril<F, A>
434
where
435
    F: fmt::SliceFormat,
436
    A: Atomicity,
437
{
438
    #[inline]
439
50.6k
    fn deref_mut(&mut self) -> &mut F::Slice {
440
50.6k
        unsafe { F::Slice::from_mut_bytes(self.as_mut_byte_slice()) }
441
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
439
50.6k
    fn deref_mut(&mut self) -> &mut F::Slice {
440
50.6k
        unsafe { F::Slice::from_mut_bytes(self.as_mut_byte_slice()) }
441
50.6k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::ops::deref::DerefMut>::deref_mut
442
}
443
444
impl<F, A> Borrow<[u8]> for Tendril<F, A>
445
where
446
    F: fmt::SliceFormat,
447
    A: Atomicity,
448
{
449
0
    fn borrow(&self) -> &[u8] {
450
0
        self.as_byte_slice()
451
0
    }
452
}
453
454
// Why not impl Borrow<str> for Tendril<fmt::UTF8>? str and [u8] hash differently,
455
// and so a HashMap<StrTendril, _> would silently break if we indexed by str. Ick.
456
// https://github.com/rust-lang/rust/issues/27108
457
458
impl<F, A> PartialEq for Tendril<F, A>
459
where
460
    F: fmt::Format,
461
    A: Atomicity,
462
{
463
    #[inline]
464
0
    fn eq(&self, other: &Self) -> bool {
465
0
        self.as_byte_slice() == other.as_byte_slice()
466
0
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::cmp::PartialEq>::eq
467
468
    #[inline]
469
0
    fn ne(&self, other: &Self) -> bool {
470
0
        self.as_byte_slice() != other.as_byte_slice()
471
0
    }
472
}
473
474
impl<F, A> Eq for Tendril<F, A>
475
where
476
    F: fmt::Format,
477
    A: Atomicity,
478
{
479
}
480
481
impl<F, A> PartialOrd for Tendril<F, A>
482
where
483
    F: fmt::SliceFormat,
484
    <F as fmt::SliceFormat>::Slice: PartialOrd,
485
    A: Atomicity,
486
{
487
    #[inline]
488
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
489
0
        PartialOrd::partial_cmp(&**self, &**other)
490
0
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8> as core::cmp::PartialOrd>::partial_cmp
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::cmp::PartialOrd>::partial_cmp
491
}
492
493
impl<F, A> Ord for Tendril<F, A>
494
where
495
    F: fmt::SliceFormat,
496
    <F as fmt::SliceFormat>::Slice: Ord,
497
    A: Atomicity,
498
{
499
    #[inline]
500
0
    fn cmp(&self, other: &Self) -> Ordering {
501
0
        Ord::cmp(&**self, &**other)
502
0
    }
503
}
504
505
impl<F, A> Default for Tendril<F, A>
506
where
507
    F: fmt::Format,
508
    A: Atomicity,
509
{
510
    #[inline(always)]
511
2.52M
    fn default() -> Tendril<F, A> {
512
2.52M
        Tendril::new()
513
2.52M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8> as core::default::Default>::default
Line
Count
Source
511
2.52M
    fn default() -> Tendril<F, A> {
512
2.52M
        Tendril::new()
513
2.52M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::default::Default>::default
514
}
515
516
impl<F, A> strfmt::Debug for Tendril<F, A>
517
where
518
    F: fmt::SliceFormat + Default + strfmt::Debug,
519
    <F as fmt::SliceFormat>::Slice: strfmt::Debug,
520
    A: Atomicity,
521
{
522
    #[inline]
523
0
    fn fmt(&self, f: &mut strfmt::Formatter) -> strfmt::Result {
524
0
        let kind = match self.ptr.get().get() {
525
0
            p if p <= MAX_INLINE_TAG => "inline",
526
0
            p if p & 1 == 1 => "shared",
527
0
            _ => "owned",
528
        };
529
530
0
        write!(f, "Tendril<{:?}>({}: ", <F as Default>::default(), kind)?;
531
0
        <<F as fmt::SliceFormat>::Slice as strfmt::Debug>::fmt(&**self, f)?;
532
0
        write!(f, ")")
533
0
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8> as core::fmt::Debug>::fmt
Unexecuted instantiation: <tendril::tendril::Tendril<_, _> as core::fmt::Debug>::fmt
534
}
535
536
impl<F, A> hash::Hash for Tendril<F, A>
537
where
538
    F: fmt::Format,
539
    A: Atomicity,
540
{
541
    #[inline]
542
0
    fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
543
0
        self.as_byte_slice().hash(hasher)
544
0
    }
545
}
546
547
impl<F, A> Tendril<F, A>
548
where
549
    F: fmt::Format,
550
    A: Atomicity,
551
{
552
    /// Create a new, empty `Tendril` in any format.
553
    #[inline(always)]
554
23.8M
    pub fn new() -> Tendril<F, A> {
555
23.8M
        unsafe { Tendril::inline(&[]) }
556
23.8M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::new
Line
Count
Source
554
50.6k
    pub fn new() -> Tendril<F, A> {
555
50.6k
        unsafe { Tendril::inline(&[]) }
556
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::new
Line
Count
Source
554
21.1M
    pub fn new() -> Tendril<F, A> {
555
21.1M
        unsafe { Tendril::inline(&[]) }
556
21.1M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::new
Line
Count
Source
554
2.63M
    pub fn new() -> Tendril<F, A> {
555
2.63M
        unsafe { Tendril::inline(&[]) }
556
2.63M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8>>::new
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::new
557
558
    /// Create a new, empty `Tendril` with a specified capacity.
559
    #[inline]
560
0
    pub fn with_capacity(capacity: u32) -> Tendril<F, A> {
561
0
        let mut t: Tendril<F, A> = Tendril::new();
562
0
        if capacity > MAX_INLINE_LEN as u32 {
563
0
            unsafe {
564
0
                t.make_owned_with_capacity(capacity);
565
0
            }
566
0
        }
567
0
        t
568
0
    }
569
570
    /// Reserve space for additional bytes.
571
    ///
572
    /// This is only a suggestion. There are cases where `Tendril` will
573
    /// decline to allocate until the buffer is actually modified.
574
    #[inline]
575
0
    pub fn reserve(&mut self, additional: u32) {
576
0
        if !self.is_shared() {
577
0
            // Don't grow a shared tendril because we'd have to copy
578
0
            // right away.
579
0
            self.force_reserve(additional);
580
0
        }
581
0
    }
582
583
    /// Reserve space for additional bytes, even for shared buffers.
584
    #[inline]
585
0
    fn force_reserve(&mut self, additional: u32) {
586
0
        let new_len = self.len32().checked_add(additional).expect(OFLOW);
587
0
        if new_len > MAX_INLINE_LEN as u32 {
588
0
            unsafe {
589
0
                self.make_owned_with_capacity(new_len);
590
0
            }
591
0
        }
592
0
    }
593
594
    /// Get the length of the `Tendril`.
595
    ///
596
    /// This is named not to conflict with `len()` on the underlying
597
    /// slice, if any.
598
    #[inline(always)]
599
937M
    pub fn len32(&self) -> u32 {
600
937M
        match self.ptr.get().get() {
601
16.9M
            EMPTY_TAG => 0,
602
920M
            n if n <= MAX_INLINE_LEN => n as u32,
603
844M
            _ => unsafe { self.raw_len() },
604
        }
605
937M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::len32
Line
Count
Source
599
11.2M
    pub fn len32(&self) -> u32 {
600
11.2M
        match self.ptr.get().get() {
601
6.26k
            EMPTY_TAG => 0,
602
11.2M
            n if n <= MAX_INLINE_LEN => n as u32,
603
5.65M
            _ => unsafe { self.raw_len() },
604
        }
605
11.2M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::len32
Line
Count
Source
599
326M
    pub fn len32(&self) -> u32 {
600
326M
        match self.ptr.get().get() {
601
50.6k
            EMPTY_TAG => 0,
602
326M
            n if n <= MAX_INLINE_LEN => n as u32,
603
325M
            _ => unsafe { self.raw_len() },
604
        }
605
326M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::len32
Line
Count
Source
599
63.6M
    pub fn len32(&self) -> u32 {
600
63.6M
        match self.ptr.get().get() {
601
7.87M
            EMPTY_TAG => 0,
602
55.7M
            n if n <= MAX_INLINE_LEN => n as u32,
603
39.5M
            _ => unsafe { self.raw_len() },
604
        }
605
63.6M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::len32
Line
Count
Source
599
8.90M
    pub fn len32(&self) -> u32 {
600
8.90M
        match self.ptr.get().get() {
601
6.33k
            EMPTY_TAG => 0,
602
8.90M
            n if n <= MAX_INLINE_LEN => n as u32,
603
8.39M
            _ => unsafe { self.raw_len() },
604
        }
605
8.90M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::len32
Line
Count
Source
599
527M
    pub fn len32(&self) -> u32 {
600
527M
        match self.ptr.get().get() {
601
9.02M
            EMPTY_TAG => 0,
602
518M
            n if n <= MAX_INLINE_LEN => n as u32,
603
465M
            _ => unsafe { self.raw_len() },
604
        }
605
527M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::len32
606
607
    /// Is the backing buffer shared?
608
    #[inline]
609
0
    pub fn is_shared(&self) -> bool {
610
0
        let n = self.ptr.get().get();
611
0
612
0
        (n > MAX_INLINE_TAG) && ((n & 1) == 1)
613
0
    }
614
615
    /// Is the backing buffer shared with this other `Tendril`?
616
    #[inline]
617
0
    pub fn is_shared_with(&self, other: &Tendril<F, A>) -> bool {
618
0
        let n = self.ptr.get().get();
619
0
620
0
        (n > MAX_INLINE_TAG) && (n == other.ptr.get().get())
621
0
    }
622
623
    /// Truncate to length 0 without discarding any owned storage.
624
    #[inline]
625
32.3M
    pub fn clear(&mut self) {
626
32.3M
        if self.ptr.get().get() <= MAX_INLINE_TAG {
627
32.3M
            self.ptr
628
32.3M
                .set(unsafe { NonZeroUsize::new_unchecked(EMPTY_TAG) });
629
32.3M
        } else {
630
23.9k
            let (_, shared, _) = unsafe { self.assume_buf() };
631
23.9k
            if shared {
632
0
                // No need to keep a reference alive for a 0-size slice.
633
0
                *self = Tendril::new();
634
23.9k
            } else {
635
23.9k
                unsafe { self.set_len(0) };
636
23.9k
            }
637
        }
638
32.3M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::clear
Line
Count
Source
625
32.3M
    pub fn clear(&mut self) {
626
32.3M
        if self.ptr.get().get() <= MAX_INLINE_TAG {
627
32.3M
            self.ptr
628
32.3M
                .set(unsafe { NonZeroUsize::new_unchecked(EMPTY_TAG) });
629
32.3M
        } else {
630
23.9k
            let (_, shared, _) = unsafe { self.assume_buf() };
631
23.9k
            if shared {
632
0
                // No need to keep a reference alive for a 0-size slice.
633
0
                *self = Tendril::new();
634
23.9k
            } else {
635
23.9k
                unsafe { self.set_len(0) };
636
23.9k
            }
637
        }
638
32.3M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::clear
639
640
    /// Build a `Tendril` by copying a byte slice, if it conforms to the format.
641
    #[inline]
642
0
    pub fn try_from_byte_slice(x: &[u8]) -> Result<Tendril<F, A>, ()> {
643
0
        match F::validate(x) {
644
0
            true => Ok(unsafe { Tendril::from_byte_slice_without_validating(x) }),
645
0
            false => Err(()),
646
        }
647
0
    }
648
649
    /// View as uninterpreted bytes.
650
    #[inline(always)]
651
11.7M
    pub fn as_bytes(&self) -> &Tendril<fmt::Bytes, A> {
652
11.7M
        unsafe { mem::transmute(self) }
653
11.7M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::as_bytes
Line
Count
Source
651
11.7M
    pub fn as_bytes(&self) -> &Tendril<fmt::Bytes, A> {
652
11.7M
        unsafe { mem::transmute(self) }
653
11.7M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::as_bytes
654
655
    /// Convert into uninterpreted bytes.
656
    #[inline(always)]
657
0
    pub fn into_bytes(self) -> Tendril<fmt::Bytes, A> {
658
0
        unsafe { mem::transmute(self) }
659
0
    }
660
661
    /// Convert `self` into a type which is `Send`.
662
    ///
663
    /// If the tendril is owned or inline, this is free,
664
    /// but if it's shared this will entail a copy of the contents.
665
    #[inline]
666
0
    pub fn into_send(mut self) -> SendTendril<F> {
667
0
        self.make_owned();
668
0
        SendTendril {
669
0
            // This changes the header.refcount from A to NonAtomic, but that's
670
0
            // OK because we have defined the format of A as a usize.
671
0
            tendril: unsafe { mem::transmute(self) },
672
0
        }
673
0
    }
674
675
    /// View as a superset format, for free.
676
    #[inline(always)]
677
0
    pub fn as_superset<Super>(&self) -> &Tendril<Super, A>
678
0
    where
679
0
        F: fmt::SubsetOf<Super>,
680
0
        Super: fmt::Format,
681
0
    {
682
0
        unsafe { mem::transmute(self) }
683
0
    }
684
685
    /// Convert into a superset format, for free.
686
    #[inline(always)]
687
0
    pub fn into_superset<Super>(self) -> Tendril<Super, A>
688
0
    where
689
0
        F: fmt::SubsetOf<Super>,
690
0
        Super: fmt::Format,
691
0
    {
692
0
        unsafe { mem::transmute(self) }
693
0
    }
694
695
    /// View as a subset format, if the `Tendril` conforms to that subset.
696
    #[inline]
697
0
    pub fn try_as_subset<Sub>(&self) -> Result<&Tendril<Sub, A>, ()>
698
0
    where
699
0
        Sub: fmt::SubsetOf<F>,
700
0
    {
701
0
        match Sub::revalidate_subset(self.as_byte_slice()) {
702
0
            true => Ok(unsafe { mem::transmute(self) }),
703
0
            false => Err(()),
704
        }
705
0
    }
706
707
    /// Convert into a subset format, if the `Tendril` conforms to that subset.
708
    #[inline]
709
0
    pub fn try_into_subset<Sub>(self) -> Result<Tendril<Sub, A>, Self>
710
0
    where
711
0
        Sub: fmt::SubsetOf<F>,
712
0
    {
713
0
        match Sub::revalidate_subset(self.as_byte_slice()) {
714
0
            true => Ok(unsafe { mem::transmute(self) }),
715
0
            false => Err(self),
716
        }
717
0
    }
718
719
    /// View as another format, if the bytes of the `Tendril` are valid for
720
    /// that format.
721
    #[inline]
722
0
    pub fn try_reinterpret_view<Other>(&self) -> Result<&Tendril<Other, A>, ()>
723
0
    where
724
0
        Other: fmt::Format,
725
0
    {
726
0
        match Other::validate(self.as_byte_slice()) {
727
0
            true => Ok(unsafe { mem::transmute(self) }),
728
0
            false => Err(()),
729
        }
730
0
    }
731
732
    /// Convert into another format, if the `Tendril` conforms to that format.
733
    ///
734
    /// This only re-validates the existing bytes under the new format. It
735
    /// will *not* change the byte content of the tendril!
736
    ///
737
    /// See the `encode` and `decode` methods for character encoding conversion.
738
    #[inline]
739
0
    pub fn try_reinterpret<Other>(self) -> Result<Tendril<Other, A>, Self>
740
0
    where
741
0
        Other: fmt::Format,
742
0
    {
743
0
        match Other::validate(self.as_byte_slice()) {
744
0
            true => Ok(unsafe { mem::transmute(self) }),
745
0
            false => Err(self),
746
        }
747
0
    }
748
749
    /// Push some bytes onto the end of the `Tendril`, if they conform to the
750
    /// format.
751
    #[inline]
752
0
    pub fn try_push_bytes(&mut self, buf: &[u8]) -> Result<(), ()> {
753
0
        match F::validate(buf) {
754
            true => unsafe {
755
0
                self.push_bytes_without_validating(buf);
756
0
                Ok(())
757
            },
758
0
            false => Err(()),
759
        }
760
0
    }
761
762
    /// Push another `Tendril` onto the end of this one.
763
    #[inline]
764
5.44M
    pub fn push_tendril(&mut self, other: &Tendril<F, A>) {
765
5.44M
        let new_len = self.len32().checked_add(other.len32()).expect(OFLOW);
766
5.44M
767
5.44M
        unsafe {
768
5.44M
            if (self.ptr.get().get() > MAX_INLINE_TAG) && (other.ptr.get().get() > MAX_INLINE_TAG) {
769
78.3k
                let (self_buf, self_shared, _) = self.assume_buf();
770
78.3k
                let (other_buf, other_shared, _) = other.assume_buf();
771
78.3k
772
78.3k
                if self_shared
773
0
                    && other_shared
774
0
                    && (self_buf.data_ptr() == other_buf.data_ptr())
775
0
                    && other.aux() == self.aux() + self.raw_len()
776
                {
777
0
                    self.set_len(new_len);
778
0
                    return;
779
78.3k
                }
780
5.36M
            }
781
782
5.44M
            self.push_bytes_without_validating(other.as_byte_slice())
783
        }
784
5.44M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::push_tendril
Line
Count
Source
764
5.44M
    pub fn push_tendril(&mut self, other: &Tendril<F, A>) {
765
5.44M
        let new_len = self.len32().checked_add(other.len32()).expect(OFLOW);
766
5.44M
767
5.44M
        unsafe {
768
5.44M
            if (self.ptr.get().get() > MAX_INLINE_TAG) && (other.ptr.get().get() > MAX_INLINE_TAG) {
769
78.3k
                let (self_buf, self_shared, _) = self.assume_buf();
770
78.3k
                let (other_buf, other_shared, _) = other.assume_buf();
771
78.3k
772
78.3k
                if self_shared
773
0
                    && other_shared
774
0
                    && (self_buf.data_ptr() == other_buf.data_ptr())
775
0
                    && other.aux() == self.aux() + self.raw_len()
776
                {
777
0
                    self.set_len(new_len);
778
0
                    return;
779
78.3k
                }
780
5.36M
            }
781
782
5.44M
            self.push_bytes_without_validating(other.as_byte_slice())
783
        }
784
5.44M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::push_tendril
785
786
    /// Attempt to slice this `Tendril` as a new `Tendril`.
787
    ///
788
    /// This will share the buffer when possible. Mutating a shared buffer
789
    /// will copy the contents.
790
    ///
791
    /// The offset and length are in bytes. The function will return
792
    /// `Err` if these are out of bounds, or if the resulting slice
793
    /// does not conform to the format.
794
    #[inline]
795
5.81M
    pub fn try_subtendril(
796
5.81M
        &self,
797
5.81M
        offset: u32,
798
5.81M
        length: u32,
799
5.81M
    ) -> Result<Tendril<F, A>, SubtendrilError> {
800
5.81M
        let self_len = self.len32();
801
5.81M
        if offset > self_len || length > (self_len - offset) {
802
0
            return Err(SubtendrilError::OutOfBounds);
803
5.81M
        }
804
5.81M
805
5.81M
        unsafe {
806
5.81M
            let byte_slice = unsafe_slice(self.as_byte_slice(), offset as usize, length as usize);
807
5.81M
            if !F::validate_subseq(byte_slice) {
808
0
                return Err(SubtendrilError::ValidationFailed);
809
5.81M
            }
810
5.81M
811
5.81M
            Ok(self.unsafe_subtendril(offset, length))
812
        }
813
5.81M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::try_subtendril
Line
Count
Source
795
3.25M
    pub fn try_subtendril(
796
3.25M
        &self,
797
3.25M
        offset: u32,
798
3.25M
        length: u32,
799
3.25M
    ) -> Result<Tendril<F, A>, SubtendrilError> {
800
3.25M
        let self_len = self.len32();
801
3.25M
        if offset > self_len || length > (self_len - offset) {
802
0
            return Err(SubtendrilError::OutOfBounds);
803
3.25M
        }
804
3.25M
805
3.25M
        unsafe {
806
3.25M
            let byte_slice = unsafe_slice(self.as_byte_slice(), offset as usize, length as usize);
807
3.25M
            if !F::validate_subseq(byte_slice) {
808
0
                return Err(SubtendrilError::ValidationFailed);
809
3.25M
            }
810
3.25M
811
3.25M
            Ok(self.unsafe_subtendril(offset, length))
812
        }
813
3.25M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::try_subtendril
Line
Count
Source
795
2.55M
    pub fn try_subtendril(
796
2.55M
        &self,
797
2.55M
        offset: u32,
798
2.55M
        length: u32,
799
2.55M
    ) -> Result<Tendril<F, A>, SubtendrilError> {
800
2.55M
        let self_len = self.len32();
801
2.55M
        if offset > self_len || length > (self_len - offset) {
802
0
            return Err(SubtendrilError::OutOfBounds);
803
2.55M
        }
804
2.55M
805
2.55M
        unsafe {
806
2.55M
            let byte_slice = unsafe_slice(self.as_byte_slice(), offset as usize, length as usize);
807
2.55M
            if !F::validate_subseq(byte_slice) {
808
0
                return Err(SubtendrilError::ValidationFailed);
809
2.55M
            }
810
2.55M
811
2.55M
            Ok(self.unsafe_subtendril(offset, length))
812
        }
813
2.55M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::try_subtendril
814
815
    /// Slice this `Tendril` as a new `Tendril`.
816
    ///
817
    /// Panics on bounds or validity check failure.
818
    #[inline]
819
5.81M
    pub fn subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
820
5.81M
        self.try_subtendril(offset, length).unwrap()
821
5.81M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::subtendril
Line
Count
Source
819
3.25M
    pub fn subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
820
3.25M
        self.try_subtendril(offset, length).unwrap()
821
3.25M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::subtendril
Line
Count
Source
819
2.55M
    pub fn subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
820
2.55M
        self.try_subtendril(offset, length).unwrap()
821
2.55M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::subtendril
822
823
    /// Try to drop `n` bytes from the front.
824
    ///
825
    /// Returns `Err` if the bytes are not available, or the suffix fails
826
    /// validation.
827
    #[inline]
828
36.5M
    pub fn try_pop_front(&mut self, n: u32) -> Result<(), SubtendrilError> {
829
36.5M
        if n == 0 {
830
6.41k
            return Ok(());
831
36.5M
        }
832
36.5M
        let old_len = self.len32();
833
36.5M
        if n > old_len {
834
0
            return Err(SubtendrilError::OutOfBounds);
835
36.5M
        }
836
36.5M
        let new_len = old_len - n;
837
36.5M
838
36.5M
        unsafe {
839
36.5M
            if !F::validate_suffix(unsafe_slice(
840
36.5M
                self.as_byte_slice(),
841
36.5M
                n as usize,
842
36.5M
                new_len as usize,
843
36.5M
            )) {
844
0
                return Err(SubtendrilError::ValidationFailed);
845
36.5M
            }
846
36.5M
847
36.5M
            self.unsafe_pop_front(n);
848
36.5M
            Ok(())
849
        }
850
36.5M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::try_pop_front
Line
Count
Source
828
340k
    pub fn try_pop_front(&mut self, n: u32) -> Result<(), SubtendrilError> {
829
340k
        if n == 0 {
830
4.02k
            return Ok(());
831
336k
        }
832
336k
        let old_len = self.len32();
833
336k
        if n > old_len {
834
0
            return Err(SubtendrilError::OutOfBounds);
835
336k
        }
836
336k
        let new_len = old_len - n;
837
336k
838
336k
        unsafe {
839
336k
            if !F::validate_suffix(unsafe_slice(
840
336k
                self.as_byte_slice(),
841
336k
                n as usize,
842
336k
                new_len as usize,
843
336k
            )) {
844
0
                return Err(SubtendrilError::ValidationFailed);
845
336k
            }
846
336k
847
336k
            self.unsafe_pop_front(n);
848
336k
            Ok(())
849
        }
850
340k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::try_pop_front
Line
Count
Source
828
36.2M
    pub fn try_pop_front(&mut self, n: u32) -> Result<(), SubtendrilError> {
829
36.2M
        if n == 0 {
830
2.39k
            return Ok(());
831
36.2M
        }
832
36.2M
        let old_len = self.len32();
833
36.2M
        if n > old_len {
834
0
            return Err(SubtendrilError::OutOfBounds);
835
36.2M
        }
836
36.2M
        let new_len = old_len - n;
837
36.2M
838
36.2M
        unsafe {
839
36.2M
            if !F::validate_suffix(unsafe_slice(
840
36.2M
                self.as_byte_slice(),
841
36.2M
                n as usize,
842
36.2M
                new_len as usize,
843
36.2M
            )) {
844
0
                return Err(SubtendrilError::ValidationFailed);
845
36.2M
            }
846
36.2M
847
36.2M
            self.unsafe_pop_front(n);
848
36.2M
            Ok(())
849
        }
850
36.2M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::try_pop_front
851
852
    /// Drop `n` bytes from the front.
853
    ///
854
    /// Panics if the bytes are not available, or the suffix fails
855
    /// validation.
856
    #[inline]
857
36.5M
    pub fn pop_front(&mut self, n: u32) {
858
36.5M
        self.try_pop_front(n).unwrap()
859
36.5M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::pop_front
Line
Count
Source
857
340k
    pub fn pop_front(&mut self, n: u32) {
858
340k
        self.try_pop_front(n).unwrap()
859
340k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::pop_front
Line
Count
Source
857
36.2M
    pub fn pop_front(&mut self, n: u32) {
858
36.2M
        self.try_pop_front(n).unwrap()
859
36.2M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::pop_front
860
861
    /// Drop `n` bytes from the back.
862
    ///
863
    /// Returns `Err` if the bytes are not available, or the prefix fails
864
    /// validation.
865
    #[inline]
866
38.5k
    pub fn try_pop_back(&mut self, n: u32) -> Result<(), SubtendrilError> {
867
38.5k
        if n == 0 {
868
26.4k
            return Ok(());
869
12.0k
        }
870
12.0k
        let old_len = self.len32();
871
12.0k
        if n > old_len {
872
0
            return Err(SubtendrilError::OutOfBounds);
873
12.0k
        }
874
12.0k
        let new_len = old_len - n;
875
12.0k
876
12.0k
        unsafe {
877
12.0k
            if !F::validate_prefix(unsafe_slice(self.as_byte_slice(), 0, new_len as usize)) {
878
0
                return Err(SubtendrilError::ValidationFailed);
879
12.0k
            }
880
12.0k
881
12.0k
            self.unsafe_pop_back(n);
882
12.0k
            Ok(())
883
        }
884
38.5k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::try_pop_back
Line
Count
Source
866
38.5k
    pub fn try_pop_back(&mut self, n: u32) -> Result<(), SubtendrilError> {
867
38.5k
        if n == 0 {
868
26.4k
            return Ok(());
869
12.0k
        }
870
12.0k
        let old_len = self.len32();
871
12.0k
        if n > old_len {
872
0
            return Err(SubtendrilError::OutOfBounds);
873
12.0k
        }
874
12.0k
        let new_len = old_len - n;
875
12.0k
876
12.0k
        unsafe {
877
12.0k
            if !F::validate_prefix(unsafe_slice(self.as_byte_slice(), 0, new_len as usize)) {
878
0
                return Err(SubtendrilError::ValidationFailed);
879
12.0k
            }
880
12.0k
881
12.0k
            self.unsafe_pop_back(n);
882
12.0k
            Ok(())
883
        }
884
38.5k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::try_pop_back
885
886
    /// Drop `n` bytes from the back.
887
    ///
888
    /// Panics if the bytes are not available, or the prefix fails
889
    /// validation.
890
    #[inline]
891
38.5k
    pub fn pop_back(&mut self, n: u32) {
892
38.5k
        self.try_pop_back(n).unwrap()
893
38.5k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::pop_back
Line
Count
Source
891
38.5k
    pub fn pop_back(&mut self, n: u32) {
892
38.5k
        self.try_pop_back(n).unwrap()
893
38.5k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::pop_back
894
895
    /// View as another format, without validating.
896
    #[inline(always)]
897
0
    pub unsafe fn reinterpret_view_without_validating<Other>(&self) -> &Tendril<Other, A>
898
0
    where
899
0
        Other: fmt::Format,
900
0
    {
901
0
        mem::transmute(self)
902
0
    }
903
904
    /// Convert into another format, without validating.
905
    #[inline(always)]
906
3.28M
    pub unsafe fn reinterpret_without_validating<Other>(self) -> Tendril<Other, A>
907
3.28M
    where
908
3.28M
        Other: fmt::Format,
909
3.28M
    {
910
3.28M
        mem::transmute(self)
911
3.28M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::reinterpret_without_validating::<tendril::fmt::UTF8>
Line
Count
Source
906
3.28M
    pub unsafe fn reinterpret_without_validating<Other>(self) -> Tendril<Other, A>
907
3.28M
    where
908
3.28M
        Other: fmt::Format,
909
3.28M
    {
910
3.28M
        mem::transmute(self)
911
3.28M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::reinterpret_without_validating::<_>
912
913
    /// Build a `Tendril` by copying a byte slice, without validating.
914
    #[inline]
915
36.2M
    pub unsafe fn from_byte_slice_without_validating(x: &[u8]) -> Tendril<F, A> {
916
36.2M
        assert!(x.len() <= buf32::MAX_LEN);
917
36.2M
        if x.len() <= MAX_INLINE_LEN {
918
36.2M
            Tendril::inline(x)
919
        } else {
920
1.21k
            Tendril::owned_copy(x)
921
        }
922
36.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::from_byte_slice_without_validating
Line
Count
Source
915
36.2M
    pub unsafe fn from_byte_slice_without_validating(x: &[u8]) -> Tendril<F, A> {
916
36.2M
        assert!(x.len() <= buf32::MAX_LEN);
917
36.2M
        if x.len() <= MAX_INLINE_LEN {
918
36.2M
            Tendril::inline(x)
919
        } else {
920
1.21k
            Tendril::owned_copy(x)
921
        }
922
36.2M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::from_byte_slice_without_validating
923
924
    /// Push some bytes onto the end of the `Tendril`, without validating.
925
    #[inline]
926
70.0M
    pub unsafe fn push_bytes_without_validating(&mut self, buf: &[u8]) {
927
70.0M
        assert!(buf.len() <= buf32::MAX_LEN);
928
929
        let Fixup {
930
70.0M
            drop_left,
931
70.0M
            drop_right,
932
70.0M
            insert_len,
933
70.0M
            insert_bytes,
934
70.0M
        } = F::fixup(self.as_byte_slice(), buf);
935
70.0M
936
70.0M
        // FIXME: think more about overflow
937
70.0M
        let adj_len = self.len32() + insert_len - drop_left;
938
70.0M
939
70.0M
        let new_len = adj_len.checked_add(buf.len() as u32).expect(OFLOW) - drop_right;
940
70.0M
941
70.0M
        let drop_left = drop_left as usize;
942
70.0M
        let drop_right = drop_right as usize;
943
70.0M
944
70.0M
        if new_len <= MAX_INLINE_LEN as u32 {
945
22.0M
            let mut tmp = [0_u8; MAX_INLINE_LEN];
946
22.0M
            {
947
22.0M
                let old = self.as_byte_slice();
948
22.0M
                let mut dest = tmp.as_mut_ptr();
949
22.0M
                copy_and_advance(&mut dest, unsafe_slice(old, 0, old.len() - drop_left));
950
22.0M
                copy_and_advance(
951
22.0M
                    &mut dest,
952
22.0M
                    unsafe_slice(&insert_bytes, 0, insert_len as usize),
953
22.0M
                );
954
22.0M
                copy_and_advance(
955
22.0M
                    &mut dest,
956
22.0M
                    unsafe_slice(buf, drop_right, buf.len() - drop_right),
957
22.0M
                );
958
22.0M
            }
959
22.0M
            *self = Tendril::inline(&tmp[..new_len as usize]);
960
48.0M
        } else {
961
48.0M
            self.make_owned_with_capacity(new_len);
962
48.0M
            let (owned, _, _) = self.assume_buf();
963
48.0M
            let mut dest = owned
964
48.0M
                .data_ptr()
965
48.0M
                .offset((owned.len as usize - drop_left) as isize);
966
48.0M
            copy_and_advance(
967
48.0M
                &mut dest,
968
48.0M
                unsafe_slice(&insert_bytes, 0, insert_len as usize),
969
48.0M
            );
970
48.0M
            copy_and_advance(
971
48.0M
                &mut dest,
972
48.0M
                unsafe_slice(buf, drop_right, buf.len() - drop_right),
973
48.0M
            );
974
48.0M
            self.set_len(new_len);
975
48.0M
        }
976
70.0M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::push_bytes_without_validating
Line
Count
Source
926
61.1M
    pub unsafe fn push_bytes_without_validating(&mut self, buf: &[u8]) {
927
61.1M
        assert!(buf.len() <= buf32::MAX_LEN);
928
929
        let Fixup {
930
61.1M
            drop_left,
931
61.1M
            drop_right,
932
61.1M
            insert_len,
933
61.1M
            insert_bytes,
934
61.1M
        } = F::fixup(self.as_byte_slice(), buf);
935
61.1M
936
61.1M
        // FIXME: think more about overflow
937
61.1M
        let adj_len = self.len32() + insert_len - drop_left;
938
61.1M
939
61.1M
        let new_len = adj_len.checked_add(buf.len() as u32).expect(OFLOW) - drop_right;
940
61.1M
941
61.1M
        let drop_left = drop_left as usize;
942
61.1M
        let drop_right = drop_right as usize;
943
61.1M
944
61.1M
        if new_len <= MAX_INLINE_LEN as u32 {
945
21.5M
            let mut tmp = [0_u8; MAX_INLINE_LEN];
946
21.5M
            {
947
21.5M
                let old = self.as_byte_slice();
948
21.5M
                let mut dest = tmp.as_mut_ptr();
949
21.5M
                copy_and_advance(&mut dest, unsafe_slice(old, 0, old.len() - drop_left));
950
21.5M
                copy_and_advance(
951
21.5M
                    &mut dest,
952
21.5M
                    unsafe_slice(&insert_bytes, 0, insert_len as usize),
953
21.5M
                );
954
21.5M
                copy_and_advance(
955
21.5M
                    &mut dest,
956
21.5M
                    unsafe_slice(buf, drop_right, buf.len() - drop_right),
957
21.5M
                );
958
21.5M
            }
959
21.5M
            *self = Tendril::inline(&tmp[..new_len as usize]);
960
39.5M
        } else {
961
39.5M
            self.make_owned_with_capacity(new_len);
962
39.5M
            let (owned, _, _) = self.assume_buf();
963
39.5M
            let mut dest = owned
964
39.5M
                .data_ptr()
965
39.5M
                .offset((owned.len as usize - drop_left) as isize);
966
39.5M
            copy_and_advance(
967
39.5M
                &mut dest,
968
39.5M
                unsafe_slice(&insert_bytes, 0, insert_len as usize),
969
39.5M
            );
970
39.5M
            copy_and_advance(
971
39.5M
                &mut dest,
972
39.5M
                unsafe_slice(buf, drop_right, buf.len() - drop_right),
973
39.5M
            );
974
39.5M
            self.set_len(new_len);
975
39.5M
        }
976
61.1M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::push_bytes_without_validating
Line
Count
Source
926
8.90M
    pub unsafe fn push_bytes_without_validating(&mut self, buf: &[u8]) {
927
8.90M
        assert!(buf.len() <= buf32::MAX_LEN);
928
929
        let Fixup {
930
8.90M
            drop_left,
931
8.90M
            drop_right,
932
8.90M
            insert_len,
933
8.90M
            insert_bytes,
934
8.90M
        } = F::fixup(self.as_byte_slice(), buf);
935
8.90M
936
8.90M
        // FIXME: think more about overflow
937
8.90M
        let adj_len = self.len32() + insert_len - drop_left;
938
8.90M
939
8.90M
        let new_len = adj_len.checked_add(buf.len() as u32).expect(OFLOW) - drop_right;
940
8.90M
941
8.90M
        let drop_left = drop_left as usize;
942
8.90M
        let drop_right = drop_right as usize;
943
8.90M
944
8.90M
        if new_len <= MAX_INLINE_LEN as u32 {
945
412k
            let mut tmp = [0_u8; MAX_INLINE_LEN];
946
412k
            {
947
412k
                let old = self.as_byte_slice();
948
412k
                let mut dest = tmp.as_mut_ptr();
949
412k
                copy_and_advance(&mut dest, unsafe_slice(old, 0, old.len() - drop_left));
950
412k
                copy_and_advance(
951
412k
                    &mut dest,
952
412k
                    unsafe_slice(&insert_bytes, 0, insert_len as usize),
953
412k
                );
954
412k
                copy_and_advance(
955
412k
                    &mut dest,
956
412k
                    unsafe_slice(buf, drop_right, buf.len() - drop_right),
957
412k
                );
958
412k
            }
959
412k
            *self = Tendril::inline(&tmp[..new_len as usize]);
960
8.49M
        } else {
961
8.49M
            self.make_owned_with_capacity(new_len);
962
8.49M
            let (owned, _, _) = self.assume_buf();
963
8.49M
            let mut dest = owned
964
8.49M
                .data_ptr()
965
8.49M
                .offset((owned.len as usize - drop_left) as isize);
966
8.49M
            copy_and_advance(
967
8.49M
                &mut dest,
968
8.49M
                unsafe_slice(&insert_bytes, 0, insert_len as usize),
969
8.49M
            );
970
8.49M
            copy_and_advance(
971
8.49M
                &mut dest,
972
8.49M
                unsafe_slice(buf, drop_right, buf.len() - drop_right),
973
8.49M
            );
974
8.49M
            self.set_len(new_len);
975
8.49M
        }
976
8.90M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::push_bytes_without_validating
977
978
    /// Slice this `Tendril` as a new `Tendril`.
979
    ///
980
    /// Does not check validity or bounds!
981
    #[inline]
982
16.3M
    pub unsafe fn unsafe_subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
983
16.3M
        if length <= MAX_INLINE_LEN as u32 {
984
14.9M
            Tendril::inline(unsafe_slice(
985
14.9M
                self.as_byte_slice(),
986
14.9M
                offset as usize,
987
14.9M
                length as usize,
988
14.9M
            ))
989
        } else {
990
1.44M
            self.make_buf_shared();
991
1.44M
            self.incref();
992
1.44M
            let (buf, _, _) = self.assume_buf();
993
1.44M
            Tendril::shared(buf, self.aux() + offset, length)
994
        }
995
16.3M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::unsafe_subtendril
Line
Count
Source
982
3.25M
    pub unsafe fn unsafe_subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
983
3.25M
        if length <= MAX_INLINE_LEN as u32 {
984
2.42M
            Tendril::inline(unsafe_slice(
985
2.42M
                self.as_byte_slice(),
986
2.42M
                offset as usize,
987
2.42M
                length as usize,
988
2.42M
            ))
989
        } else {
990
832k
            self.make_buf_shared();
991
832k
            self.incref();
992
832k
            let (buf, _, _) = self.assume_buf();
993
832k
            Tendril::shared(buf, self.aux() + offset, length)
994
        }
995
3.25M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::unsafe_subtendril
Line
Count
Source
982
13.1M
    pub unsafe fn unsafe_subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
983
13.1M
        if length <= MAX_INLINE_LEN as u32 {
984
12.5M
            Tendril::inline(unsafe_slice(
985
12.5M
                self.as_byte_slice(),
986
12.5M
                offset as usize,
987
12.5M
                length as usize,
988
12.5M
            ))
989
        } else {
990
607k
            self.make_buf_shared();
991
607k
            self.incref();
992
607k
            let (buf, _, _) = self.assume_buf();
993
607k
            Tendril::shared(buf, self.aux() + offset, length)
994
        }
995
13.1M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::unsafe_subtendril
996
997
    /// Drop `n` bytes from the front.
998
    ///
999
    /// Does not check validity or bounds!
1000
    #[inline]
1001
96.1M
    pub unsafe fn unsafe_pop_front(&mut self, n: u32) {
1002
96.1M
        let new_len = self.len32() - n;
1003
96.1M
        if new_len <= MAX_INLINE_LEN as u32 {
1004
15.6M
            *self = Tendril::inline(unsafe_slice(
1005
15.6M
                self.as_byte_slice(),
1006
15.6M
                n as usize,
1007
15.6M
                new_len as usize,
1008
15.6M
            ));
1009
80.5M
        } else {
1010
80.5M
            self.make_buf_shared();
1011
80.5M
            self.set_aux(self.aux() + n);
1012
80.5M
            let len = self.raw_len();
1013
80.5M
            self.set_len(len - n);
1014
80.5M
        }
1015
96.1M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::unsafe_pop_front
Line
Count
Source
1001
36.2M
    pub unsafe fn unsafe_pop_front(&mut self, n: u32) {
1002
36.2M
        let new_len = self.len32() - n;
1003
36.2M
        if new_len <= MAX_INLINE_LEN as u32 {
1004
89.2k
            *self = Tendril::inline(unsafe_slice(
1005
89.2k
                self.as_byte_slice(),
1006
89.2k
                n as usize,
1007
89.2k
                new_len as usize,
1008
89.2k
            ));
1009
36.1M
        } else {
1010
36.1M
            self.make_buf_shared();
1011
36.1M
            self.set_aux(self.aux() + n);
1012
36.1M
            let len = self.raw_len();
1013
36.1M
            self.set_len(len - n);
1014
36.1M
        }
1015
36.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::unsafe_pop_front
Line
Count
Source
1001
59.9M
    pub unsafe fn unsafe_pop_front(&mut self, n: u32) {
1002
59.9M
        let new_len = self.len32() - n;
1003
59.9M
        if new_len <= MAX_INLINE_LEN as u32 {
1004
15.5M
            *self = Tendril::inline(unsafe_slice(
1005
15.5M
                self.as_byte_slice(),
1006
15.5M
                n as usize,
1007
15.5M
                new_len as usize,
1008
15.5M
            ));
1009
44.4M
        } else {
1010
44.4M
            self.make_buf_shared();
1011
44.4M
            self.set_aux(self.aux() + n);
1012
44.4M
            let len = self.raw_len();
1013
44.4M
            self.set_len(len - n);
1014
44.4M
        }
1015
59.9M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::unsafe_pop_front
1016
1017
    /// Drop `n` bytes from the back.
1018
    ///
1019
    /// Does not check validity or bounds!
1020
    #[inline]
1021
12.0k
    pub unsafe fn unsafe_pop_back(&mut self, n: u32) {
1022
12.0k
        let new_len = self.len32() - n;
1023
12.0k
        if new_len <= MAX_INLINE_LEN as u32 {
1024
3.20k
            *self = Tendril::inline(unsafe_slice(self.as_byte_slice(), 0, new_len as usize));
1025
8.86k
        } else {
1026
8.86k
            self.make_buf_shared();
1027
8.86k
            let len = self.raw_len();
1028
8.86k
            self.set_len(len - n);
1029
8.86k
        }
1030
12.0k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::unsafe_pop_back
Line
Count
Source
1021
12.0k
    pub unsafe fn unsafe_pop_back(&mut self, n: u32) {
1022
12.0k
        let new_len = self.len32() - n;
1023
12.0k
        if new_len <= MAX_INLINE_LEN as u32 {
1024
3.20k
            *self = Tendril::inline(unsafe_slice(self.as_byte_slice(), 0, new_len as usize));
1025
8.86k
        } else {
1026
8.86k
            self.make_buf_shared();
1027
8.86k
            let len = self.raw_len();
1028
8.86k
            self.set_len(len - n);
1029
8.86k
        }
1030
12.0k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::unsafe_pop_back
1031
1032
    #[inline]
1033
1.47M
    unsafe fn incref(&self) {
1034
1.47M
        (*self.header()).refcount.increment();
1035
1.47M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::incref
Line
Count
Source
1033
832k
    unsafe fn incref(&self) {
1034
832k
        (*self.header()).refcount.increment();
1035
832k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::incref
Line
Count
Source
1033
638k
    unsafe fn incref(&self) {
1034
638k
        (*self.header()).refcount.increment();
1035
638k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::incref
1036
1037
    #[inline]
1038
82.0M
    unsafe fn make_buf_shared(&self) {
1039
82.0M
        let p = self.ptr.get().get();
1040
82.0M
        if p & 1 == 0 {
1041
452k
            let header = p as *mut Header<A>;
1042
452k
            (*header).cap = self.aux();
1043
452k
1044
452k
            self.ptr.set(NonZeroUsize::new_unchecked(p | 1));
1045
452k
            self.set_aux(0);
1046
81.6M
        }
1047
82.0M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::make_buf_shared
Line
Count
Source
1038
36.9M
    unsafe fn make_buf_shared(&self) {
1039
36.9M
        let p = self.ptr.get().get();
1040
36.9M
        if p & 1 == 0 {
1041
30.1k
            let header = p as *mut Header<A>;
1042
30.1k
            (*header).cap = self.aux();
1043
30.1k
1044
30.1k
            self.ptr.set(NonZeroUsize::new_unchecked(p | 1));
1045
30.1k
            self.set_aux(0);
1046
36.9M
        }
1047
36.9M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::make_buf_shared
Line
Count
Source
1038
45.0M
    unsafe fn make_buf_shared(&self) {
1039
45.0M
        let p = self.ptr.get().get();
1040
45.0M
        if p & 1 == 0 {
1041
422k
            let header = p as *mut Header<A>;
1042
422k
            (*header).cap = self.aux();
1043
422k
1044
422k
            self.ptr.set(NonZeroUsize::new_unchecked(p | 1));
1045
422k
            self.set_aux(0);
1046
44.6M
        }
1047
45.0M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::make_buf_shared
1048
1049
    // This is not public as it is of no practical value to users.
1050
    // By and large they shouldn't need to worry about the distinction at all,
1051
    // and going out of your way to make it owned is pointless.
1052
    #[inline]
1053
48.1M
    fn make_owned(&mut self) {
1054
48.1M
        unsafe {
1055
48.1M
            let ptr = self.ptr.get().get();
1056
48.1M
            if ptr <= MAX_INLINE_TAG || (ptr & 1) == 1 {
1057
1.33M
                *self = Tendril::owned_copy(self.as_byte_slice());
1058
46.7M
            }
1059
        }
1060
48.1M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::make_owned
Line
Count
Source
1053
101k
    fn make_owned(&mut self) {
1054
101k
        unsafe {
1055
101k
            let ptr = self.ptr.get().get();
1056
101k
            if ptr <= MAX_INLINE_TAG || (ptr & 1) == 1 {
1057
50.6k
                *self = Tendril::owned_copy(self.as_byte_slice());
1058
50.6k
            }
1059
        }
1060
101k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::make_owned
Line
Count
Source
1053
39.5M
    fn make_owned(&mut self) {
1054
39.5M
        unsafe {
1055
39.5M
            let ptr = self.ptr.get().get();
1056
39.5M
            if ptr <= MAX_INLINE_TAG || (ptr & 1) == 1 {
1057
1.17M
                *self = Tendril::owned_copy(self.as_byte_slice());
1058
38.3M
            }
1059
        }
1060
39.5M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::make_owned
Line
Count
Source
1053
8.49M
    fn make_owned(&mut self) {
1054
8.49M
        unsafe {
1055
8.49M
            let ptr = self.ptr.get().get();
1056
8.49M
            if ptr <= MAX_INLINE_TAG || (ptr & 1) == 1 {
1057
104k
                *self = Tendril::owned_copy(self.as_byte_slice());
1058
8.39M
            }
1059
        }
1060
8.49M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::make_owned
1061
1062
    #[inline]
1063
48.0M
    unsafe fn make_owned_with_capacity(&mut self, cap: u32) {
1064
48.0M
        self.make_owned();
1065
48.0M
        let mut buf = self.assume_buf().0;
1066
48.0M
        buf.grow(cap);
1067
48.0M
        self.ptr.set(NonZeroUsize::new_unchecked(buf.ptr as usize));
1068
48.0M
        self.set_aux(buf.cap);
1069
48.0M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::make_owned_with_capacity
Line
Count
Source
1063
50.6k
    unsafe fn make_owned_with_capacity(&mut self, cap: u32) {
1064
50.6k
        self.make_owned();
1065
50.6k
        let mut buf = self.assume_buf().0;
1066
50.6k
        buf.grow(cap);
1067
50.6k
        self.ptr.set(NonZeroUsize::new_unchecked(buf.ptr as usize));
1068
50.6k
        self.set_aux(buf.cap);
1069
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::make_owned_with_capacity
Line
Count
Source
1063
39.5M
    unsafe fn make_owned_with_capacity(&mut self, cap: u32) {
1064
39.5M
        self.make_owned();
1065
39.5M
        let mut buf = self.assume_buf().0;
1066
39.5M
        buf.grow(cap);
1067
39.5M
        self.ptr.set(NonZeroUsize::new_unchecked(buf.ptr as usize));
1068
39.5M
        self.set_aux(buf.cap);
1069
39.5M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::make_owned_with_capacity
Line
Count
Source
1063
8.49M
    unsafe fn make_owned_with_capacity(&mut self, cap: u32) {
1064
8.49M
        self.make_owned();
1065
8.49M
        let mut buf = self.assume_buf().0;
1066
8.49M
        buf.grow(cap);
1067
8.49M
        self.ptr.set(NonZeroUsize::new_unchecked(buf.ptr as usize));
1068
8.49M
        self.set_aux(buf.cap);
1069
8.49M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::make_owned_with_capacity
1070
1071
    #[inline(always)]
1072
388M
    unsafe fn header(&self) -> *mut Header<A> {
1073
388M
        (self.ptr.get().get() & !1) as *mut Header<A>
1074
388M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::header
Line
Count
Source
1072
126M
    unsafe fn header(&self) -> *mut Header<A> {
1073
126M
        (self.ptr.get().get() & !1) as *mut Header<A>
1074
126M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::header
Line
Count
Source
1072
261M
    unsafe fn header(&self) -> *mut Header<A> {
1073
261M
        (self.ptr.get().get() & !1) as *mut Header<A>
1074
261M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::header
1075
1076
    #[inline]
1077
384M
    unsafe fn assume_buf(&self) -> (Buf32<Header<A>>, bool, u32) {
1078
384M
        let ptr = self.ptr.get().get();
1079
384M
        let header = self.header();
1080
384M
        let shared = (ptr & 1) == 1;
1081
384M
        let (cap, offset) = match shared {
1082
234M
            true => ((*header).cap, self.aux()),
1083
150M
            false => (self.aux(), 0),
1084
        };
1085
1086
384M
        (
1087
384M
            Buf32 {
1088
384M
                ptr: header,
1089
384M
                len: offset + self.len32(),
1090
384M
                cap: cap,
1091
384M
            },
1092
384M
            shared,
1093
384M
            offset,
1094
384M
        )
1095
384M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::assume_buf
Line
Count
Source
1077
125M
    unsafe fn assume_buf(&self) -> (Buf32<Header<A>>, bool, u32) {
1078
125M
        let ptr = self.ptr.get().get();
1079
125M
        let header = self.header();
1080
125M
        let shared = (ptr & 1) == 1;
1081
125M
        let (cap, offset) = match shared {
1082
125M
            true => ((*header).cap, self.aux()),
1083
220k
            false => (self.aux(), 0),
1084
        };
1085
1086
125M
        (
1087
125M
            Buf32 {
1088
125M
                ptr: header,
1089
125M
                len: offset + self.len32(),
1090
125M
                cap: cap,
1091
125M
            },
1092
125M
            shared,
1093
125M
            offset,
1094
125M
        )
1095
125M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::assume_buf
Line
Count
Source
1077
259M
    unsafe fn assume_buf(&self) -> (Buf32<Header<A>>, bool, u32) {
1078
259M
        let ptr = self.ptr.get().get();
1079
259M
        let header = self.header();
1080
259M
        let shared = (ptr & 1) == 1;
1081
259M
        let (cap, offset) = match shared {
1082
108M
            true => ((*header).cap, self.aux()),
1083
150M
            false => (self.aux(), 0),
1084
        };
1085
1086
259M
        (
1087
259M
            Buf32 {
1088
259M
                ptr: header,
1089
259M
                len: offset + self.len32(),
1090
259M
                cap: cap,
1091
259M
            },
1092
259M
            shared,
1093
259M
            offset,
1094
259M
        )
1095
259M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::assume_buf
1096
1097
    #[inline]
1098
112M
    unsafe fn inline(x: &[u8]) -> Tendril<F, A> {
1099
112M
        let len = x.len();
1100
112M
        let t = Tendril {
1101
112M
            ptr: Cell::new(inline_tag(len as u32)),
1102
112M
            buf: UnsafeCell::new(Buffer { inline: [0; 8] }),
1103
112M
            marker: PhantomData,
1104
112M
            refcount_marker: PhantomData,
1105
112M
        };
1106
112M
        ptr::copy_nonoverlapping(x.as_ptr(), (*t.buf.get()).inline.as_mut_ptr(), len);
1107
112M
        t
1108
112M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::inline
Line
Count
Source
1098
2.56M
    unsafe fn inline(x: &[u8]) -> Tendril<F, A> {
1099
2.56M
        let len = x.len();
1100
2.56M
        let t = Tendril {
1101
2.56M
            ptr: Cell::new(inline_tag(len as u32)),
1102
2.56M
            buf: UnsafeCell::new(Buffer { inline: [0; 8] }),
1103
2.56M
            marker: PhantomData,
1104
2.56M
            refcount_marker: PhantomData,
1105
2.56M
        };
1106
2.56M
        ptr::copy_nonoverlapping(x.as_ptr(), (*t.buf.get()).inline.as_mut_ptr(), len);
1107
2.56M
        t
1108
2.56M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::inline
Line
Count
Source
1098
110M
    unsafe fn inline(x: &[u8]) -> Tendril<F, A> {
1099
110M
        let len = x.len();
1100
110M
        let t = Tendril {
1101
110M
            ptr: Cell::new(inline_tag(len as u32)),
1102
110M
            buf: UnsafeCell::new(Buffer { inline: [0; 8] }),
1103
110M
            marker: PhantomData,
1104
110M
            refcount_marker: PhantomData,
1105
110M
        };
1106
110M
        ptr::copy_nonoverlapping(x.as_ptr(), (*t.buf.get()).inline.as_mut_ptr(), len);
1107
110M
        t
1108
110M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::inline
1109
1110
    #[inline]
1111
1.33M
    unsafe fn owned(x: Buf32<Header<A>>) -> Tendril<F, A> {
1112
1.33M
        Tendril {
1113
1.33M
            ptr: Cell::new(NonZeroUsize::new_unchecked(x.ptr as usize)),
1114
1.33M
            buf: UnsafeCell::new(Buffer {
1115
1.33M
                heap: Heap {
1116
1.33M
                    len: x.len,
1117
1.33M
                    aux: x.cap,
1118
1.33M
                },
1119
1.33M
            }),
1120
1.33M
            marker: PhantomData,
1121
1.33M
            refcount_marker: PhantomData,
1122
1.33M
        }
1123
1.33M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::owned
Line
Count
Source
1111
50.6k
    unsafe fn owned(x: Buf32<Header<A>>) -> Tendril<F, A> {
1112
50.6k
        Tendril {
1113
50.6k
            ptr: Cell::new(NonZeroUsize::new_unchecked(x.ptr as usize)),
1114
50.6k
            buf: UnsafeCell::new(Buffer {
1115
50.6k
                heap: Heap {
1116
50.6k
                    len: x.len,
1117
50.6k
                    aux: x.cap,
1118
50.6k
                },
1119
50.6k
            }),
1120
50.6k
            marker: PhantomData,
1121
50.6k
            refcount_marker: PhantomData,
1122
50.6k
        }
1123
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::owned
Line
Count
Source
1111
1.17M
    unsafe fn owned(x: Buf32<Header<A>>) -> Tendril<F, A> {
1112
1.17M
        Tendril {
1113
1.17M
            ptr: Cell::new(NonZeroUsize::new_unchecked(x.ptr as usize)),
1114
1.17M
            buf: UnsafeCell::new(Buffer {
1115
1.17M
                heap: Heap {
1116
1.17M
                    len: x.len,
1117
1.17M
                    aux: x.cap,
1118
1.17M
                },
1119
1.17M
            }),
1120
1.17M
            marker: PhantomData,
1121
1.17M
            refcount_marker: PhantomData,
1122
1.17M
        }
1123
1.17M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::owned
Line
Count
Source
1111
105k
    unsafe fn owned(x: Buf32<Header<A>>) -> Tendril<F, A> {
1112
105k
        Tendril {
1113
105k
            ptr: Cell::new(NonZeroUsize::new_unchecked(x.ptr as usize)),
1114
105k
            buf: UnsafeCell::new(Buffer {
1115
105k
                heap: Heap {
1116
105k
                    len: x.len,
1117
105k
                    aux: x.cap,
1118
105k
                },
1119
105k
            }),
1120
105k
            marker: PhantomData,
1121
105k
            refcount_marker: PhantomData,
1122
105k
        }
1123
105k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::owned
1124
1125
    #[inline]
1126
1.33M
    unsafe fn owned_copy(x: &[u8]) -> Tendril<F, A> {
1127
1.33M
        let len32 = x.len() as u32;
1128
1.33M
        let mut b = Buf32::with_capacity(len32, Header::new());
1129
1.33M
        ptr::copy_nonoverlapping(x.as_ptr(), b.data_ptr(), x.len());
1130
1.33M
        b.len = len32;
1131
1.33M
        Tendril::owned(b)
1132
1.33M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::owned_copy
Line
Count
Source
1126
50.6k
    unsafe fn owned_copy(x: &[u8]) -> Tendril<F, A> {
1127
50.6k
        let len32 = x.len() as u32;
1128
50.6k
        let mut b = Buf32::with_capacity(len32, Header::new());
1129
50.6k
        ptr::copy_nonoverlapping(x.as_ptr(), b.data_ptr(), x.len());
1130
50.6k
        b.len = len32;
1131
50.6k
        Tendril::owned(b)
1132
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::owned_copy
Line
Count
Source
1126
1.17M
    unsafe fn owned_copy(x: &[u8]) -> Tendril<F, A> {
1127
1.17M
        let len32 = x.len() as u32;
1128
1.17M
        let mut b = Buf32::with_capacity(len32, Header::new());
1129
1.17M
        ptr::copy_nonoverlapping(x.as_ptr(), b.data_ptr(), x.len());
1130
1.17M
        b.len = len32;
1131
1.17M
        Tendril::owned(b)
1132
1.17M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::owned_copy
Line
Count
Source
1126
105k
    unsafe fn owned_copy(x: &[u8]) -> Tendril<F, A> {
1127
105k
        let len32 = x.len() as u32;
1128
105k
        let mut b = Buf32::with_capacity(len32, Header::new());
1129
105k
        ptr::copy_nonoverlapping(x.as_ptr(), b.data_ptr(), x.len());
1130
105k
        b.len = len32;
1131
105k
        Tendril::owned(b)
1132
105k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::owned_copy
1133
1134
    #[inline]
1135
1.44M
    unsafe fn shared(buf: Buf32<Header<A>>, off: u32, len: u32) -> Tendril<F, A> {
1136
1.44M
        Tendril {
1137
1.44M
            ptr: Cell::new(NonZeroUsize::new_unchecked((buf.ptr as usize) | 1)),
1138
1.44M
            buf: UnsafeCell::new(Buffer {
1139
1.44M
                heap: Heap { len, aux: off },
1140
1.44M
            }),
1141
1.44M
            marker: PhantomData,
1142
1.44M
            refcount_marker: PhantomData,
1143
1.44M
        }
1144
1.44M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::shared
Line
Count
Source
1135
832k
    unsafe fn shared(buf: Buf32<Header<A>>, off: u32, len: u32) -> Tendril<F, A> {
1136
832k
        Tendril {
1137
832k
            ptr: Cell::new(NonZeroUsize::new_unchecked((buf.ptr as usize) | 1)),
1138
832k
            buf: UnsafeCell::new(Buffer {
1139
832k
                heap: Heap { len, aux: off },
1140
832k
            }),
1141
832k
            marker: PhantomData,
1142
832k
            refcount_marker: PhantomData,
1143
832k
        }
1144
832k
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::shared
Line
Count
Source
1135
607k
    unsafe fn shared(buf: Buf32<Header<A>>, off: u32, len: u32) -> Tendril<F, A> {
1136
607k
        Tendril {
1137
607k
            ptr: Cell::new(NonZeroUsize::new_unchecked((buf.ptr as usize) | 1)),
1138
607k
            buf: UnsafeCell::new(Buffer {
1139
607k
                heap: Heap { len, aux: off },
1140
607k
            }),
1141
607k
            marker: PhantomData,
1142
607k
            refcount_marker: PhantomData,
1143
607k
        }
1144
607k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::shared
1145
1146
    #[inline]
1147
527M
    fn as_byte_slice<'a>(&'a self) -> &'a [u8] {
1148
527M
        unsafe {
1149
527M
            match self.ptr.get().get() {
1150
62.0M
                EMPTY_TAG => &[],
1151
464M
                n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked(..n),
1152
                _ => {
1153
284M
                    let (buf, _, offset) = self.assume_buf();
1154
284M
                    copy_lifetime(
1155
284M
                        self,
1156
284M
                        unsafe_slice(buf.data(), offset as usize, self.len32() as usize),
1157
284M
                    )
1158
                }
1159
            }
1160
        }
1161
527M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::as_byte_slice
Line
Count
Source
1147
126M
    fn as_byte_slice<'a>(&'a self) -> &'a [u8] {
1148
126M
        unsafe {
1149
126M
            match self.ptr.get().get() {
1150
58.5k
                EMPTY_TAG => &[],
1151
126M
                n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked(..n),
1152
                _ => {
1153
124M
                    let (buf, _, offset) = self.assume_buf();
1154
124M
                    copy_lifetime(
1155
124M
                        self,
1156
124M
                        unsafe_slice(buf.data(), offset as usize, self.len32() as usize),
1157
124M
                    )
1158
                }
1159
            }
1160
        }
1161
126M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::as_byte_slice
Line
Count
Source
1147
400M
    fn as_byte_slice<'a>(&'a self) -> &'a [u8] {
1148
400M
        unsafe {
1149
400M
            match self.ptr.get().get() {
1150
62.0M
                EMPTY_TAG => &[],
1151
338M
                n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked(..n),
1152
                _ => {
1153
159M
                    let (buf, _, offset) = self.assume_buf();
1154
159M
                    copy_lifetime(
1155
159M
                        self,
1156
159M
                        unsafe_slice(buf.data(), offset as usize, self.len32() as usize),
1157
159M
                    )
1158
                }
1159
            }
1160
        }
1161
400M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::as_byte_slice
1162
1163
    // There's no need to worry about locking on an atomic Tendril, because it makes it unique as
1164
    // soon as you do that.
1165
    #[inline]
1166
50.6k
    fn as_mut_byte_slice<'a>(&'a mut self) -> &'a mut [u8] {
1167
50.6k
        unsafe {
1168
50.6k
            match self.ptr.get().get() {
1169
0
                EMPTY_TAG => &mut [],
1170
50.6k
                n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked_mut(..n),
1171
                _ => {
1172
50.6k
                    self.make_owned();
1173
50.6k
                    let (mut buf, _, offset) = self.assume_buf();
1174
50.6k
                    let len = self.len32() as usize;
1175
50.6k
                    copy_lifetime_mut(self, unsafe_slice_mut(buf.data_mut(), offset as usize, len))
1176
                }
1177
            }
1178
        }
1179
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::as_mut_byte_slice
Line
Count
Source
1166
50.6k
    fn as_mut_byte_slice<'a>(&'a mut self) -> &'a mut [u8] {
1167
50.6k
        unsafe {
1168
50.6k
            match self.ptr.get().get() {
1169
0
                EMPTY_TAG => &mut [],
1170
50.6k
                n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked_mut(..n),
1171
                _ => {
1172
50.6k
                    self.make_owned();
1173
50.6k
                    let (mut buf, _, offset) = self.assume_buf();
1174
50.6k
                    let len = self.len32() as usize;
1175
50.6k
                    copy_lifetime_mut(self, unsafe_slice_mut(buf.data_mut(), offset as usize, len))
1176
                }
1177
            }
1178
        }
1179
50.6k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::as_mut_byte_slice
1180
1181
925M
    unsafe fn raw_len(&self) -> u32 {
1182
925M
        (*self.buf.get()).heap.len
1183
925M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::raw_len
Line
Count
Source
1181
362M
    unsafe fn raw_len(&self) -> u32 {
1182
362M
        (*self.buf.get()).heap.len
1183
362M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::raw_len
Line
Count
Source
1181
563M
    unsafe fn raw_len(&self) -> u32 {
1182
563M
        (*self.buf.get()).heap.len
1183
563M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::raw_len
1184
1185
128M
    unsafe fn set_len(&mut self, len: u32) {
1186
128M
        (*self.buf.get()).heap.len = len;
1187
128M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::set_len
Line
Count
Source
1185
36.2M
    unsafe fn set_len(&mut self, len: u32) {
1186
36.2M
        (*self.buf.get()).heap.len = len;
1187
36.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::set_len
Line
Count
Source
1185
92.4M
    unsafe fn set_len(&mut self, len: u32) {
1186
92.4M
        (*self.buf.get()).heap.len = len;
1187
92.4M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::set_len
1188
1189
467M
    unsafe fn aux(&self) -> u32 {
1190
467M
        (*self.buf.get()).heap.aux
1191
467M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::aux
Line
Count
Source
1189
162M
    unsafe fn aux(&self) -> u32 {
1190
162M
        (*self.buf.get()).heap.aux
1191
162M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::aux
Line
Count
Source
1189
304M
    unsafe fn aux(&self) -> u32 {
1190
304M
        (*self.buf.get()).heap.aux
1191
304M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::aux
1192
1193
129M
    unsafe fn set_aux(&self, aux: u32) {
1194
129M
        (*self.buf.get()).heap.aux = aux;
1195
129M
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::set_aux
Line
Count
Source
1193
36.2M
    unsafe fn set_aux(&self, aux: u32) {
1194
36.2M
        (*self.buf.get()).heap.aux = aux;
1195
36.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::set_aux
Line
Count
Source
1193
92.8M
    unsafe fn set_aux(&self, aux: u32) {
1194
92.8M
        (*self.buf.get()).heap.aux = aux;
1195
92.8M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::set_aux
1196
}
1197
1198
impl<F, A> Tendril<F, A>
1199
where
1200
    F: fmt::SliceFormat,
1201
    A: Atomicity,
1202
{
1203
    /// Build a `Tendril` by copying a slice.
1204
    #[inline]
1205
36.2M
    pub fn from_slice(x: &F::Slice) -> Tendril<F, A> {
1206
36.2M
        unsafe { Tendril::from_byte_slice_without_validating(x.as_bytes()) }
1207
36.2M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::from_slice
Line
Count
Source
1205
36.2M
    pub fn from_slice(x: &F::Slice) -> Tendril<F, A> {
1206
36.2M
        unsafe { Tendril::from_byte_slice_without_validating(x.as_bytes()) }
1207
36.2M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::from_slice
1208
1209
    /// Push a slice onto the end of the `Tendril`.
1210
    #[inline]
1211
3.46M
    pub fn push_slice(&mut self, x: &F::Slice) {
1212
3.46M
        unsafe { self.push_bytes_without_validating(x.as_bytes()) }
1213
3.46M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::push_slice
Line
Count
Source
1211
3.46M
    pub fn push_slice(&mut self, x: &F::Slice) {
1212
3.46M
        unsafe { self.push_bytes_without_validating(x.as_bytes()) }
1213
3.46M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::push_slice
1214
}
1215
1216
/// A simple wrapper to make `Tendril` `Send`.
1217
///
1218
/// Although there is a certain subset of the operations on a `Tendril` that a `SendTendril` could
1219
/// reasonably implement, in order to clearly separate concerns this type is deliberately
1220
/// minimalist, acting as a safe encapsulation around the invariants which permit `Send`ness and
1221
/// behaving as an opaque object.
1222
///
1223
/// A `SendTendril` may be produced by `Tendril.into_send()` or `SendTendril::from(tendril)`,
1224
/// and may be returned to a `Tendril` by `Tendril::from(self)`.
1225
#[derive(Clone)]
1226
pub struct SendTendril<F>
1227
where
1228
    F: fmt::Format,
1229
{
1230
    tendril: Tendril<F>,
1231
}
1232
1233
unsafe impl<F> Send for SendTendril<F> where F: fmt::Format {}
1234
1235
impl<F, A> From<Tendril<F, A>> for SendTendril<F>
1236
where
1237
    F: fmt::Format,
1238
    A: Atomicity,
1239
{
1240
    #[inline]
1241
0
    fn from(tendril: Tendril<F, A>) -> SendTendril<F> {
1242
0
        tendril.into_send()
1243
0
    }
1244
}
1245
1246
impl<F, A> From<SendTendril<F>> for Tendril<F, A>
1247
where
1248
    F: fmt::Format,
1249
    A: Atomicity,
1250
{
1251
    #[inline]
1252
0
    fn from(send: SendTendril<F>) -> Tendril<F, A> {
1253
0
        unsafe { mem::transmute(send.tendril) }
1254
0
        // header.refcount may have been initialised as an Atomic or a NonAtomic, but the value
1255
0
        // will be the same (1) regardless, because the layout is defined.
1256
0
        // Thus we don't need to fiddle about resetting it or anything like that.
1257
0
    }
1258
}
1259
1260
/// `Tendril`-related methods for Rust slices.
1261
pub trait SliceExt<F>: fmt::Slice
1262
where
1263
    F: fmt::SliceFormat<Slice = Self>,
1264
{
1265
    /// Make a `Tendril` from this slice.
1266
    #[inline]
1267
0
    fn to_tendril(&self) -> Tendril<F> {
1268
0
        // It should be done thusly, but at the time of writing the defaults don't help inference:
1269
0
        //fn to_tendril<A = NonAtomic>(&self) -> Tendril<Self::Format, A>
1270
0
        //    where A: Atomicity,
1271
0
        //{
1272
0
        Tendril::from_slice(self)
1273
0
    }
1274
}
1275
1276
impl SliceExt<fmt::UTF8> for str {}
1277
impl SliceExt<fmt::Bytes> for [u8] {}
1278
1279
impl<F, A> Tendril<F, A>
1280
where
1281
    F: for<'a> fmt::CharFormat<'a>,
1282
    A: Atomicity,
1283
{
1284
    /// Remove and return the first character, if any.
1285
    #[inline]
1286
81.1M
    pub fn pop_front_char<'a>(&'a mut self) -> Option<char> {
1287
81.1M
        unsafe {
1288
81.1M
            let next_char; // first char in iterator
1289
81.1M
            let mut skip = 0; // number of bytes to skip, or 0 to clear
1290
81.1M
1291
81.1M
            {
1292
81.1M
                // <--+
1293
81.1M
                //  |  Creating an iterator borrows self, so introduce a
1294
81.1M
                //  +- scope to contain the borrow (that way we can mutate
1295
81.1M
                //     self below, after this scope exits).
1296
81.1M
1297
81.1M
                let mut iter = F::char_indices(self.as_byte_slice());
1298
81.1M
                match iter.next() {
1299
81.1M
                    Some((_, c)) => {
1300
81.1M
                        next_char = Some(c);
1301
81.1M
                        if let Some((n, _)) = iter.next() {
1302
49.0M
                            skip = n as u32;
1303
49.0M
                        }
1304
                    }
1305
0
                    None => {
1306
0
                        next_char = None;
1307
0
                    }
1308
                }
1309
            }
1310
1311
81.1M
            if skip != 0 {
1312
49.0M
                self.unsafe_pop_front(skip);
1313
49.0M
            } else {
1314
32.0M
                self.clear();
1315
32.0M
            }
1316
1317
81.1M
            next_char
1318
81.1M
        }
1319
81.1M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::pop_front_char
Line
Count
Source
1286
81.1M
    pub fn pop_front_char<'a>(&'a mut self) -> Option<char> {
1287
81.1M
        unsafe {
1288
81.1M
            let next_char; // first char in iterator
1289
81.1M
            let mut skip = 0; // number of bytes to skip, or 0 to clear
1290
81.1M
1291
81.1M
            {
1292
81.1M
                // <--+
1293
81.1M
                //  |  Creating an iterator borrows self, so introduce a
1294
81.1M
                //  +- scope to contain the borrow (that way we can mutate
1295
81.1M
                //     self below, after this scope exits).
1296
81.1M
1297
81.1M
                let mut iter = F::char_indices(self.as_byte_slice());
1298
81.1M
                match iter.next() {
1299
81.1M
                    Some((_, c)) => {
1300
81.1M
                        next_char = Some(c);
1301
81.1M
                        if let Some((n, _)) = iter.next() {
1302
49.0M
                            skip = n as u32;
1303
49.0M
                        }
1304
                    }
1305
0
                    None => {
1306
0
                        next_char = None;
1307
0
                    }
1308
                }
1309
            }
1310
1311
81.1M
            if skip != 0 {
1312
49.0M
                self.unsafe_pop_front(skip);
1313
49.0M
            } else {
1314
32.0M
                self.clear();
1315
32.0M
            }
1316
1317
81.1M
            next_char
1318
81.1M
        }
1319
81.1M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::pop_front_char
1320
1321
    /// Remove and return a run of characters at the front of the `Tendril`
1322
    /// which are classified the same according to the function `classify`.
1323
    ///
1324
    /// Returns `None` on an empty string.
1325
    #[inline]
1326
0
    pub fn pop_front_char_run<'a, C, R>(&'a mut self, mut classify: C) -> Option<(Tendril<F, A>, R)>
1327
0
    where
1328
0
        C: FnMut(char) -> R,
1329
0
        R: PartialEq,
1330
0
    {
1331
0
        let (class, first_mismatch);
1332
0
        {
1333
0
            let mut chars = unsafe { F::char_indices(self.as_byte_slice()) };
1334
0
            let (_, first) = unwrap_or_return!(chars.next(), None);
1335
0
            class = classify(first);
1336
0
            first_mismatch = chars.find(|&(_, ch)| &classify(ch) != &class);
1337
0
        }
1338
0
1339
0
        match first_mismatch {
1340
0
            Some((idx, _)) => unsafe {
1341
0
                let t = self.unsafe_subtendril(0, idx as u32);
1342
0
                self.unsafe_pop_front(idx as u32);
1343
0
                Some((t, class))
1344
            },
1345
            None => {
1346
0
                let t = self.clone();
1347
0
                self.clear();
1348
0
                Some((t, class))
1349
            }
1350
        }
1351
0
    }
1352
1353
    /// Push a character, if it can be represented in this format.
1354
    #[inline]
1355
0
    pub fn try_push_char(&mut self, c: char) -> Result<(), ()> {
1356
0
        F::encode_char(c, |b| unsafe {
1357
0
            self.push_bytes_without_validating(b);
1358
0
        })
1359
0
    }
1360
}
1361
1362
/// Extension trait for `io::Read`.
1363
pub trait ReadExt: io::Read {
1364
    fn read_to_tendril<A>(&mut self, buf: &mut Tendril<fmt::Bytes, A>) -> io::Result<usize>
1365
    where
1366
        A: Atomicity;
1367
}
1368
1369
impl<T> ReadExt for T
1370
where
1371
    T: io::Read,
1372
{
1373
    /// Read all bytes until EOF.
1374
0
    fn read_to_tendril<A>(&mut self, buf: &mut Tendril<fmt::Bytes, A>) -> io::Result<usize>
1375
0
    where
1376
0
        A: Atomicity,
1377
0
    {
1378
        // Adapted from libstd/io/mod.rs.
1379
        const DEFAULT_BUF_SIZE: u32 = 64 * 1024;
1380
1381
0
        let start_len = buf.len();
1382
0
        let mut len = start_len;
1383
0
        let mut new_write_size = 16;
1384
        let ret;
1385
        loop {
1386
0
            if len == buf.len() {
1387
0
                if new_write_size < DEFAULT_BUF_SIZE {
1388
0
                    new_write_size *= 2;
1389
0
                }
1390
                // FIXME: this exposes uninitialized bytes to a generic R type
1391
                // this is fine for R=File which never reads these bytes,
1392
                // but user-defined types might.
1393
                // The standard library pushes zeros to `Vec<u8>` for that reason.
1394
0
                unsafe {
1395
0
                    buf.push_uninitialized(new_write_size);
1396
0
                }
1397
0
            }
1398
1399
0
            match self.read(&mut buf[len..]) {
1400
                Ok(0) => {
1401
0
                    ret = Ok(len - start_len);
1402
0
                    break;
1403
                }
1404
0
                Ok(n) => len += n,
1405
0
                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
1406
0
                Err(e) => {
1407
0
                    ret = Err(e);
1408
0
                    break;
1409
                }
1410
            }
1411
        }
1412
1413
0
        let buf_len = buf.len32();
1414
0
        buf.pop_back(buf_len - (len as u32));
1415
0
        ret
1416
0
    }
1417
}
1418
1419
impl<A> io::Write for Tendril<fmt::Bytes, A>
1420
where
1421
    A: Atomicity,
1422
{
1423
    #[inline]
1424
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1425
0
        self.push_slice(buf);
1426
0
        Ok(buf.len())
1427
0
    }
1428
1429
    #[inline]
1430
0
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
1431
0
        self.push_slice(buf);
1432
0
        Ok(())
1433
0
    }
1434
1435
    #[inline(always)]
1436
0
    fn flush(&mut self) -> io::Result<()> {
1437
0
        Ok(())
1438
0
    }
1439
}
1440
1441
#[cfg(feature = "encoding")]
1442
impl<A> encoding::ByteWriter for Tendril<fmt::Bytes, A>
1443
where
1444
    A: Atomicity,
1445
{
1446
    #[inline]
1447
    fn write_byte(&mut self, b: u8) {
1448
        self.push_slice(&[b]);
1449
    }
1450
1451
    #[inline]
1452
    fn write_bytes(&mut self, v: &[u8]) {
1453
        self.push_slice(v);
1454
    }
1455
1456
    #[inline]
1457
    fn writer_hint(&mut self, additional: usize) {
1458
        self.reserve(::std::cmp::min(u32::MAX as usize, additional) as u32);
1459
    }
1460
}
1461
1462
impl<F, A> Tendril<F, A>
1463
where
1464
    A: Atomicity,
1465
    F: fmt::SliceFormat<Slice = [u8]>,
1466
{
1467
    /// Decode from some character encoding into UTF-8.
1468
    ///
1469
    /// See the [rust-encoding docs](https://lifthrasiir.github.io/rust-encoding/encoding/)
1470
    /// for more information.
1471
    #[inline]
1472
    #[cfg(feature = "encoding")]
1473
    pub fn decode(
1474
        &self,
1475
        encoding: EncodingRef,
1476
        trap: DecoderTrap,
1477
    ) -> Result<Tendril<fmt::UTF8, A>, ::std::borrow::Cow<'static, str>> {
1478
        let mut ret = Tendril::new();
1479
        encoding.decode_to(&*self, trap, &mut ret).map(|_| ret)
1480
    }
1481
1482
    /// Push "uninitialized bytes" onto the end.
1483
    ///
1484
    /// Really, this grows the tendril without writing anything to the new area.
1485
    /// It's only defined for byte tendrils because it's only useful if you
1486
    /// plan to then mutate the buffer.
1487
    #[inline]
1488
50.6k
    pub unsafe fn push_uninitialized(&mut self, n: u32) {
1489
50.6k
        let new_len = self.len32().checked_add(n).expect(OFLOW);
1490
50.6k
        if new_len <= MAX_INLINE_LEN as u32 && self.ptr.get().get() <= MAX_INLINE_TAG {
1491
0
            self.ptr.set(inline_tag(new_len))
1492
50.6k
        } else {
1493
50.6k
            self.make_owned_with_capacity(new_len);
1494
50.6k
            self.set_len(new_len);
1495
50.6k
        }
1496
50.6k
    }
<tendril::tendril::Tendril<tendril::fmt::Bytes>>::push_uninitialized
Line
Count
Source
1488
50.6k
    pub unsafe fn push_uninitialized(&mut self, n: u32) {
1489
50.6k
        let new_len = self.len32().checked_add(n).expect(OFLOW);
1490
50.6k
        if new_len <= MAX_INLINE_LEN as u32 && self.ptr.get().get() <= MAX_INLINE_TAG {
1491
0
            self.ptr.set(inline_tag(new_len))
1492
50.6k
        } else {
1493
50.6k
            self.make_owned_with_capacity(new_len);
1494
50.6k
            self.set_len(new_len);
1495
50.6k
        }
1496
50.6k
    }
Unexecuted instantiation: <tendril::tendril::Tendril<_, _>>::push_uninitialized
1497
}
1498
1499
impl<A> strfmt::Display for Tendril<fmt::UTF8, A>
1500
where
1501
    A: Atomicity,
1502
{
1503
    #[inline]
1504
0
    fn fmt(&self, f: &mut strfmt::Formatter) -> strfmt::Result {
1505
0
        <str as strfmt::Display>::fmt(&**self, f)
1506
0
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8> as core::fmt::Display>::fmt
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8, _> as core::fmt::Display>::fmt
1507
}
1508
1509
impl<A> str::FromStr for Tendril<fmt::UTF8, A>
1510
where
1511
    A: Atomicity,
1512
{
1513
    type Err = ();
1514
1515
    #[inline]
1516
0
    fn from_str(s: &str) -> Result<Self, ()> {
1517
0
        Ok(Tendril::from_slice(s))
1518
0
    }
1519
}
1520
1521
impl<A> strfmt::Write for Tendril<fmt::UTF8, A>
1522
where
1523
    A: Atomicity,
1524
{
1525
    #[inline]
1526
0
    fn write_str(&mut self, s: &str) -> strfmt::Result {
1527
0
        self.push_slice(s);
1528
0
        Ok(())
1529
0
    }
1530
}
1531
1532
#[cfg(feature = "encoding")]
1533
impl<A> encoding::StringWriter for Tendril<fmt::UTF8, A>
1534
where
1535
    A: Atomicity,
1536
{
1537
    #[inline]
1538
    fn write_char(&mut self, c: char) {
1539
        self.push_char(c);
1540
    }
1541
1542
    #[inline]
1543
    fn write_str(&mut self, s: &str) {
1544
        self.push_slice(s);
1545
    }
1546
1547
    #[inline]
1548
    fn writer_hint(&mut self, additional: usize) {
1549
        self.reserve(::std::cmp::min(u32::MAX as usize, additional) as u32);
1550
    }
1551
}
1552
1553
impl<A> Tendril<fmt::UTF8, A>
1554
where
1555
    A: Atomicity,
1556
{
1557
    /// Encode from UTF-8 into some other character encoding.
1558
    ///
1559
    /// See the [rust-encoding docs](https://lifthrasiir.github.io/rust-encoding/encoding/)
1560
    /// for more information.
1561
    #[inline]
1562
    #[cfg(feature = "encoding")]
1563
    pub fn encode(
1564
        &self,
1565
        encoding: EncodingRef,
1566
        trap: EncoderTrap,
1567
    ) -> Result<Tendril<fmt::Bytes, A>, ::std::borrow::Cow<'static, str>> {
1568
        let mut ret = Tendril::new();
1569
        encoding.encode_to(&*self, trap, &mut ret).map(|_| ret)
1570
    }
1571
1572
    /// Push a character onto the end.
1573
    #[inline]
1574
61.1M
    pub fn push_char(&mut self, c: char) {
1575
61.1M
        unsafe {
1576
61.1M
            self.push_bytes_without_validating(c.encode_utf8(&mut [0_u8; 4]).as_bytes());
1577
61.1M
        }
1578
61.1M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::push_char
Line
Count
Source
1574
61.1M
    pub fn push_char(&mut self, c: char) {
1575
61.1M
        unsafe {
1576
61.1M
            self.push_bytes_without_validating(c.encode_utf8(&mut [0_u8; 4]).as_bytes());
1577
61.1M
        }
1578
61.1M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8, _>>::push_char
1579
1580
    /// Create a `Tendril` from a single character.
1581
    #[inline]
1582
2.48M
    pub fn from_char(c: char) -> Tendril<fmt::UTF8, A> {
1583
2.48M
        let mut t: Tendril<fmt::UTF8, A> = Tendril::new();
1584
2.48M
        t.push_char(c);
1585
2.48M
        t
1586
2.48M
    }
<tendril::tendril::Tendril<tendril::fmt::UTF8>>::from_char
Line
Count
Source
1582
2.48M
    pub fn from_char(c: char) -> Tendril<fmt::UTF8, A> {
1583
2.48M
        let mut t: Tendril<fmt::UTF8, A> = Tendril::new();
1584
2.48M
        t.push_char(c);
1585
2.48M
        t
1586
2.48M
    }
Unexecuted instantiation: <tendril::tendril::Tendril<tendril::fmt::UTF8, _>>::from_char
1587
1588
    /// Helper for the `format_tendril!` macro.
1589
    #[inline]
1590
0
    pub fn format(args: strfmt::Arguments) -> Tendril<fmt::UTF8, A> {
1591
        use std::fmt::Write;
1592
0
        let mut output: Tendril<fmt::UTF8, A> = Tendril::new();
1593
0
        let _ = write!(&mut output, "{}", args);
1594
0
        output
1595
0
    }
1596
}
1597
1598
/// Create a `StrTendril` through string formatting.
1599
///
1600
/// Works just like the standard `format!` macro.
1601
#[macro_export]
1602
macro_rules! format_tendril {
1603
    ($($arg:tt)*) => ($crate::StrTendril::format(format_args!($($arg)*)))
1604
}
1605
1606
impl<'a, F, A> From<&'a F::Slice> for Tendril<F, A>
1607
where
1608
    F: fmt::SliceFormat,
1609
    A: Atomicity,
1610
{
1611
    #[inline]
1612
0
    fn from(input: &F::Slice) -> Tendril<F, A> {
1613
0
        Tendril::from_slice(input)
1614
0
    }
1615
}
1616
1617
impl<A> From<String> for Tendril<fmt::UTF8, A>
1618
where
1619
    A: Atomicity,
1620
{
1621
    #[inline]
1622
0
    fn from(input: String) -> Tendril<fmt::UTF8, A> {
1623
0
        Tendril::from_slice(&*input)
1624
0
    }
1625
}
1626
1627
impl<F, A> AsRef<F::Slice> for Tendril<F, A>
1628
where
1629
    F: fmt::SliceFormat,
1630
    A: Atomicity,
1631
{
1632
    #[inline]
1633
0
    fn as_ref(&self) -> &F::Slice {
1634
0
        &**self
1635
0
    }
1636
}
1637
1638
impl<A> From<Tendril<fmt::UTF8, A>> for String
1639
where
1640
    A: Atomicity,
1641
{
1642
    #[inline]
1643
0
    fn from(input: Tendril<fmt::UTF8, A>) -> String {
1644
0
        String::from(&*input)
1645
0
    }
1646
}
1647
1648
impl<'a, A> From<&'a Tendril<fmt::UTF8, A>> for String
1649
where
1650
    A: Atomicity,
1651
{
1652
    #[inline]
1653
0
    fn from(input: &'a Tendril<fmt::UTF8, A>) -> String {
1654
0
        String::from(&**input)
1655
0
    }
1656
}
1657
1658
#[cfg(all(test, feature = "bench"))]
1659
#[path = "bench.rs"]
1660
mod bench;
1661
1662
#[cfg(test)]
1663
mod test {
1664
    use super::{
1665
        Atomic, ByteTendril, Header, NonAtomic, ReadExt, SendTendril, SliceExt, StrTendril, Tendril,
1666
    };
1667
    use fmt;
1668
    use std::iter;
1669
    use std::thread;
1670
1671
    fn assert_send<T: Send>() {}
1672
1673
    #[test]
1674
    fn smoke_test() {
1675
        assert_eq!("", &*"".to_tendril());
1676
        assert_eq!("abc", &*"abc".to_tendril());
1677
        assert_eq!("Hello, world!", &*"Hello, world!".to_tendril());
1678
1679
        assert_eq!(b"", &*b"".to_tendril());
1680
        assert_eq!(b"abc", &*b"abc".to_tendril());
1681
        assert_eq!(b"Hello, world!", &*b"Hello, world!".to_tendril());
1682
    }
1683
1684
    #[test]
1685
    fn assert_sizes() {
1686
        use std::mem;
1687
        struct EmptyWithDrop;
1688
        impl Drop for EmptyWithDrop {
1689
            fn drop(&mut self) {}
1690
        }
1691
        let compiler_uses_inline_drop_flags = mem::size_of::<EmptyWithDrop>() > 0;
1692
1693
        let correct = mem::size_of::<*const ()>()
1694
            + 8
1695
            + if compiler_uses_inline_drop_flags {
1696
                1
1697
            } else {
1698
                0
1699
            };
1700
1701
        assert_eq!(correct, mem::size_of::<ByteTendril>());
1702
        assert_eq!(correct, mem::size_of::<StrTendril>());
1703
1704
        assert_eq!(correct, mem::size_of::<Option<ByteTendril>>());
1705
        assert_eq!(correct, mem::size_of::<Option<StrTendril>>());
1706
1707
        assert_eq!(
1708
            mem::size_of::<*const ()>() * 2,
1709
            mem::size_of::<Header<Atomic>>(),
1710
        );
1711
        assert_eq!(
1712
            mem::size_of::<Header<Atomic>>(),
1713
            mem::size_of::<Header<NonAtomic>>(),
1714
        );
1715
    }
1716
1717
    #[test]
1718
    fn validate_utf8() {
1719
        assert!(ByteTendril::try_from_byte_slice(b"\xFF").is_ok());
1720
        assert!(StrTendril::try_from_byte_slice(b"\xFF").is_err());
1721
        assert!(StrTendril::try_from_byte_slice(b"\xEA\x99\xFF").is_err());
1722
        assert!(StrTendril::try_from_byte_slice(b"\xEA\x99").is_err());
1723
        assert!(StrTendril::try_from_byte_slice(b"\xEA\x99\xAE\xEA").is_err());
1724
        assert_eq!(
1725
            "\u{a66e}",
1726
            &*StrTendril::try_from_byte_slice(b"\xEA\x99\xAE").unwrap()
1727
        );
1728
1729
        let mut t = StrTendril::new();
1730
        assert!(t.try_push_bytes(b"\xEA\x99").is_err());
1731
        assert!(t.try_push_bytes(b"\xAE").is_err());
1732
        assert!(t.try_push_bytes(b"\xEA\x99\xAE").is_ok());
1733
        assert_eq!("\u{a66e}", &*t);
1734
    }
1735
1736
    #[test]
1737
    fn share_and_unshare() {
1738
        let s = b"foobarbaz".to_tendril();
1739
        assert_eq!(b"foobarbaz", &*s);
1740
        assert!(!s.is_shared());
1741
1742
        let mut t = s.clone();
1743
        assert_eq!(s.as_ptr(), t.as_ptr());
1744
        assert!(s.is_shared());
1745
        assert!(t.is_shared());
1746
1747
        t.push_slice(b"quux");
1748
        assert_eq!(b"foobarbaz", &*s);
1749
        assert_eq!(b"foobarbazquux", &*t);
1750
        assert!(s.as_ptr() != t.as_ptr());
1751
        assert!(!t.is_shared());
1752
    }
1753
1754
    #[test]
1755
    fn format_display() {
1756
        assert_eq!("foobar", &*format!("{}", "foobar".to_tendril()));
1757
1758
        let mut s = "foo".to_tendril();
1759
        assert_eq!("foo", &*format!("{}", s));
1760
1761
        let t = s.clone();
1762
        assert_eq!("foo", &*format!("{}", s));
1763
        assert_eq!("foo", &*format!("{}", t));
1764
1765
        s.push_slice("barbaz!");
1766
        assert_eq!("foobarbaz!", &*format!("{}", s));
1767
        assert_eq!("foo", &*format!("{}", t));
1768
    }
1769
1770
    #[test]
1771
    fn format_debug() {
1772
        assert_eq!(
1773
            r#"Tendril<UTF8>(inline: "foobar")"#,
1774
            &*format!("{:?}", "foobar".to_tendril())
1775
        );
1776
        assert_eq!(
1777
            r#"Tendril<Bytes>(inline: [102, 111, 111, 98, 97, 114])"#,
1778
            &*format!("{:?}", b"foobar".to_tendril())
1779
        );
1780
1781
        let t = "anextralongstring".to_tendril();
1782
        assert_eq!(
1783
            r#"Tendril<UTF8>(owned: "anextralongstring")"#,
1784
            &*format!("{:?}", t)
1785
        );
1786
        let _ = t.clone();
1787
        assert_eq!(
1788
            r#"Tendril<UTF8>(shared: "anextralongstring")"#,
1789
            &*format!("{:?}", t)
1790
        );
1791
    }
1792
1793
    #[test]
1794
    fn subtendril() {
1795
        assert_eq!("foo".to_tendril(), "foo-bar".to_tendril().subtendril(0, 3));
1796
        assert_eq!("bar".to_tendril(), "foo-bar".to_tendril().subtendril(4, 3));
1797
1798
        let mut t = "foo-bar".to_tendril();
1799
        t.pop_front(2);
1800
        assert_eq!("o-bar".to_tendril(), t);
1801
        t.pop_back(1);
1802
        assert_eq!("o-ba".to_tendril(), t);
1803
1804
        assert_eq!(
1805
            "foo".to_tendril(),
1806
            "foo-a-longer-string-bar-baz".to_tendril().subtendril(0, 3)
1807
        );
1808
        assert_eq!(
1809
            "oo-a-".to_tendril(),
1810
            "foo-a-longer-string-bar-baz".to_tendril().subtendril(1, 5)
1811
        );
1812
        assert_eq!(
1813
            "bar".to_tendril(),
1814
            "foo-a-longer-string-bar-baz".to_tendril().subtendril(20, 3)
1815
        );
1816
1817
        let mut t = "another rather long string".to_tendril();
1818
        t.pop_front(2);
1819
        assert!(t.starts_with("other rather"));
1820
        t.pop_back(1);
1821
        assert_eq!("other rather long strin".to_tendril(), t);
1822
        assert!(t.is_shared());
1823
    }
1824
1825
    #[test]
1826
    fn subtendril_invalid() {
1827
        assert!("\u{a66e}".to_tendril().try_subtendril(0, 2).is_err());
1828
        assert!("\u{a66e}".to_tendril().try_subtendril(1, 2).is_err());
1829
1830
        assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 3).is_err());
1831
        assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 2).is_err());
1832
        assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 1).is_err());
1833
        assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 3).is_err());
1834
        assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 2).is_err());
1835
        assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 1).is_err());
1836
        assert!("\u{1f4a9}".to_tendril().try_subtendril(2, 2).is_err());
1837
        assert!("\u{1f4a9}".to_tendril().try_subtendril(2, 1).is_err());
1838
        assert!("\u{1f4a9}".to_tendril().try_subtendril(3, 1).is_err());
1839
1840
        let mut t = "\u{1f4a9}zzzzzz".to_tendril();
1841
        assert!(t.try_pop_front(1).is_err());
1842
        assert!(t.try_pop_front(2).is_err());
1843
        assert!(t.try_pop_front(3).is_err());
1844
        assert!(t.try_pop_front(4).is_ok());
1845
        assert_eq!("zzzzzz", &*t);
1846
1847
        let mut t = "zzzzzz\u{1f4a9}".to_tendril();
1848
        assert!(t.try_pop_back(1).is_err());
1849
        assert!(t.try_pop_back(2).is_err());
1850
        assert!(t.try_pop_back(3).is_err());
1851
        assert!(t.try_pop_back(4).is_ok());
1852
        assert_eq!("zzzzzz", &*t);
1853
    }
1854
1855
    #[test]
1856
    fn conversion() {
1857
        assert_eq!(
1858
            &[0x66, 0x6F, 0x6F].to_tendril(),
1859
            "foo".to_tendril().as_bytes()
1860
        );
1861
        assert_eq!(
1862
            [0x66, 0x6F, 0x6F].to_tendril(),
1863
            "foo".to_tendril().into_bytes()
1864
        );
1865
1866
        let ascii: Tendril<fmt::ASCII> = b"hello".to_tendril().try_reinterpret().unwrap();
1867
        assert_eq!(&"hello".to_tendril(), ascii.as_superset());
1868
        assert_eq!("hello".to_tendril(), ascii.clone().into_superset());
1869
1870
        assert!(b"\xFF"
1871
            .to_tendril()
1872
            .try_reinterpret::<fmt::ASCII>()
1873
            .is_err());
1874
1875
        let t = "hello".to_tendril();
1876
        let ascii: &Tendril<fmt::ASCII> = t.try_as_subset().unwrap();
1877
        assert_eq!(b"hello", &**ascii.as_bytes());
1878
1879
        assert!("ő"
1880
            .to_tendril()
1881
            .try_reinterpret_view::<fmt::ASCII>()
1882
            .is_err());
1883
        assert!("ő".to_tendril().try_as_subset::<fmt::ASCII>().is_err());
1884
1885
        let ascii: Tendril<fmt::ASCII> = "hello".to_tendril().try_into_subset().unwrap();
1886
        assert_eq!(b"hello", &**ascii.as_bytes());
1887
1888
        assert!("ő".to_tendril().try_reinterpret::<fmt::ASCII>().is_err());
1889
        assert!("ő".to_tendril().try_into_subset::<fmt::ASCII>().is_err());
1890
    }
1891
1892
    #[test]
1893
    fn clear() {
1894
        let mut t = "foo-".to_tendril();
1895
        t.clear();
1896
        assert_eq!(t.len(), 0);
1897
        assert_eq!(t.len32(), 0);
1898
        assert_eq!(&*t, "");
1899
1900
        let mut t = "much longer".to_tendril();
1901
        let s = t.clone();
1902
        t.clear();
1903
        assert_eq!(t.len(), 0);
1904
        assert_eq!(t.len32(), 0);
1905
        assert_eq!(&*t, "");
1906
        assert_eq!(&*s, "much longer");
1907
    }
1908
1909
    #[test]
1910
    fn push_tendril() {
1911
        let mut t = "abc".to_tendril();
1912
        t.push_tendril(&"xyz".to_tendril());
1913
        assert_eq!("abcxyz", &*t);
1914
    }
1915
1916
    #[test]
1917
    fn wtf8() {
1918
        assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xA0\xBD").is_ok());
1919
        assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xB2\xA9").is_ok());
1920
        assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xA0\xBD\xED\xB2\xA9").is_err());
1921
1922
        let t: Tendril<fmt::WTF8> =
1923
            Tendril::try_from_byte_slice(b"\xED\xA0\xBD\xEA\x99\xAE").unwrap();
1924
        assert!(b"\xED\xA0\xBD".to_tendril().try_reinterpret().unwrap() == t.subtendril(0, 3));
1925
        assert!(b"\xEA\x99\xAE".to_tendril().try_reinterpret().unwrap() == t.subtendril(3, 3));
1926
        assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
1927
1928
        assert!(t.try_subtendril(0, 1).is_err());
1929
        assert!(t.try_subtendril(0, 2).is_err());
1930
        assert!(t.try_subtendril(1, 1).is_err());
1931
1932
        assert!(t.try_subtendril(3, 1).is_err());
1933
        assert!(t.try_subtendril(3, 2).is_err());
1934
        assert!(t.try_subtendril(4, 1).is_err());
1935
1936
        // paired surrogates
1937
        let mut t: Tendril<fmt::WTF8> = Tendril::try_from_byte_slice(b"\xED\xA0\xBD").unwrap();
1938
        assert!(t.try_push_bytes(b"\xED\xB2\xA9").is_ok());
1939
        assert_eq!(b"\xF0\x9F\x92\xA9", t.as_byte_slice());
1940
        assert!(t.try_reinterpret_view::<fmt::UTF8>().is_ok());
1941
1942
        // unpaired surrogates
1943
        let mut t: Tendril<fmt::WTF8> = Tendril::try_from_byte_slice(b"\xED\xA0\xBB").unwrap();
1944
        assert!(t.try_push_bytes(b"\xED\xA0").is_err());
1945
        assert!(t.try_push_bytes(b"\xED").is_err());
1946
        assert!(t.try_push_bytes(b"\xA0").is_err());
1947
        assert!(t.try_push_bytes(b"\xED\xA0\xBD").is_ok());
1948
        assert_eq!(b"\xED\xA0\xBB\xED\xA0\xBD", t.as_byte_slice());
1949
        assert!(t.try_push_bytes(b"\xED\xB2\xA9").is_ok());
1950
        assert_eq!(b"\xED\xA0\xBB\xF0\x9F\x92\xA9", t.as_byte_slice());
1951
        assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
1952
    }
1953
1954
    #[test]
1955
    fn front_char() {
1956
        let mut t = "".to_tendril();
1957
        assert_eq!(None, t.pop_front_char());
1958
        assert_eq!(None, t.pop_front_char());
1959
1960
        let mut t = "abc".to_tendril();
1961
        assert_eq!(Some('a'), t.pop_front_char());
1962
        assert_eq!(Some('b'), t.pop_front_char());
1963
        assert_eq!(Some('c'), t.pop_front_char());
1964
        assert_eq!(None, t.pop_front_char());
1965
        assert_eq!(None, t.pop_front_char());
1966
1967
        let mut t = "főo-a-longer-string-bar-baz".to_tendril();
1968
        assert_eq!(28, t.len());
1969
        assert_eq!(Some('f'), t.pop_front_char());
1970
        assert_eq!(Some('ő'), t.pop_front_char());
1971
        assert_eq!(Some('o'), t.pop_front_char());
1972
        assert_eq!(Some('-'), t.pop_front_char());
1973
        assert_eq!(23, t.len());
1974
    }
1975
1976
    #[test]
1977
    fn char_run() {
1978
        for &(s, exp) in &[
1979
            ("", None),
1980
            (" ", Some((" ", true))),
1981
            ("x", Some(("x", false))),
1982
            ("  \t  \n", Some(("  \t  \n", true))),
1983
            ("xyzzy", Some(("xyzzy", false))),
1984
            ("   xyzzy", Some(("   ", true))),
1985
            ("xyzzy   ", Some(("xyzzy", false))),
1986
            ("   xyzzy  ", Some(("   ", true))),
1987
            ("xyzzy   hi", Some(("xyzzy", false))),
1988
            ("中 ", Some(("中", false))),
1989
            (" 中 ", Some((" ", true))),
1990
            ("  中 ", Some(("  ", true))),
1991
            ("   中 ", Some(("   ", true))),
1992
        ] {
1993
            let mut t = s.to_tendril();
1994
            let res = t.pop_front_char_run(char::is_whitespace);
1995
            match exp {
1996
                None => assert!(res.is_none()),
1997
                Some((es, ec)) => {
1998
                    let (rt, rc) = res.unwrap();
1999
                    assert_eq!(es, &*rt);
2000
                    assert_eq!(ec, rc);
2001
                }
2002
            }
2003
        }
2004
    }
2005
2006
    #[test]
2007
    fn deref_mut_inline() {
2008
        let mut t = "xyő".to_tendril().into_bytes();
2009
        t[3] = 0xff;
2010
        assert_eq!(b"xy\xC5\xFF", &*t);
2011
        assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
2012
        t[3] = 0x8b;
2013
        assert_eq!("xyŋ", &**t.try_reinterpret_view::<fmt::UTF8>().unwrap());
2014
2015
        unsafe {
2016
            t.push_uninitialized(3);
2017
            t[4] = 0xEA;
2018
            t[5] = 0x99;
2019
            t[6] = 0xAE;
2020
            assert_eq!(
2021
                "xyŋ\u{a66e}",
2022
                &**t.try_reinterpret_view::<fmt::UTF8>().unwrap()
2023
            );
2024
            t.push_uninitialized(20);
2025
            t.pop_back(20);
2026
            assert_eq!(
2027
                "xyŋ\u{a66e}",
2028
                &**t.try_reinterpret_view::<fmt::UTF8>().unwrap()
2029
            );
2030
        }
2031
    }
2032
2033
    #[test]
2034
    fn deref_mut() {
2035
        let mut t = b"0123456789".to_tendril();
2036
        let u = t.clone();
2037
        assert!(t.is_shared());
2038
        t[9] = 0xff;
2039
        assert!(!t.is_shared());
2040
        assert_eq!(b"0123456789", &*u);
2041
        assert_eq!(b"012345678\xff", &*t);
2042
    }
2043
2044
    #[test]
2045
    fn push_char() {
2046
        let mut t = "xyz".to_tendril();
2047
        t.push_char('o');
2048
        assert_eq!("xyzo", &*t);
2049
        t.push_char('ő');
2050
        assert_eq!("xyzoő", &*t);
2051
        t.push_char('\u{a66e}');
2052
        assert_eq!("xyzoő\u{a66e}", &*t);
2053
        t.push_char('\u{1f4a9}');
2054
        assert_eq!("xyzoő\u{a66e}\u{1f4a9}", &*t);
2055
        assert_eq!(t.len(), 13);
2056
    }
2057
2058
    #[test]
2059
    #[cfg(feature = "encoding")]
2060
    fn encode() {
2061
        use encoding::{all, EncoderTrap};
2062
2063
        let t = "안녕하세요 러스트".to_tendril();
2064
        assert_eq!(
2065
            b"\xbe\xc8\xb3\xe7\xc7\xcf\xbc\xbc\xbf\xe4\x20\xb7\xaf\xbd\xba\xc6\xae",
2066
            &*t.encode(all::WINDOWS_949, EncoderTrap::Strict).unwrap()
2067
        );
2068
2069
        let t = "Энергия пробуждения ия-я-я! \u{a66e}".to_tendril();
2070
        assert_eq!(
2071
            b"\xfc\xce\xc5\xd2\xc7\xc9\xd1 \xd0\xd2\xcf\xc2\xd5\xd6\xc4\xc5\xce\
2072
                     \xc9\xd1 \xc9\xd1\x2d\xd1\x2d\xd1\x21 ?",
2073
            &*t.encode(all::KOI8_U, EncoderTrap::Replace).unwrap()
2074
        );
2075
2076
        let t = "\u{1f4a9}".to_tendril();
2077
        assert!(t.encode(all::WINDOWS_1252, EncoderTrap::Strict).is_err());
2078
    }
2079
2080
    #[test]
2081
    #[cfg(feature = "encoding")]
2082
    fn decode() {
2083
        use encoding::{all, DecoderTrap};
2084
2085
        let t = b"\xbe\xc8\xb3\xe7\xc7\xcf\xbc\xbc\
2086
                  \xbf\xe4\x20\xb7\xaf\xbd\xba\xc6\xae"
2087
            .to_tendril();
2088
        assert_eq!(
2089
            "안녕하세요 러스트",
2090
            &*t.decode(all::WINDOWS_949, DecoderTrap::Strict).unwrap()
2091
        );
2092
2093
        let t = b"\xfc\xce\xc5\xd2\xc7\xc9\xd1 \xd0\xd2\xcf\xc2\xd5\xd6\xc4\xc5\xce\
2094
                  \xc9\xd1 \xc9\xd1\x2d\xd1\x2d\xd1\x21"
2095
            .to_tendril();
2096
        assert_eq!(
2097
            "Энергия пробуждения ия-я-я!",
2098
            &*t.decode(all::KOI8_U, DecoderTrap::Replace).unwrap()
2099
        );
2100
2101
        let t = b"x \xff y".to_tendril();
2102
        assert!(t.decode(all::UTF_8, DecoderTrap::Strict).is_err());
2103
2104
        let t = b"x \xff y".to_tendril();
2105
        assert_eq!(
2106
            "x \u{fffd} y",
2107
            &*t.decode(all::UTF_8, DecoderTrap::Replace).unwrap()
2108
        );
2109
    }
2110
2111
    #[test]
2112
    fn ascii() {
2113
        fn mk(x: &[u8]) -> Tendril<fmt::ASCII> {
2114
            x.to_tendril().try_reinterpret().unwrap()
2115
        }
2116
2117
        let mut t = mk(b"xyz");
2118
        assert_eq!(Some('x'), t.pop_front_char());
2119
        assert_eq!(Some('y'), t.pop_front_char());
2120
        assert_eq!(Some('z'), t.pop_front_char());
2121
        assert_eq!(None, t.pop_front_char());
2122
2123
        let mut t = mk(b" \t xyz");
2124
        assert!(Some((mk(b" \t "), true)) == t.pop_front_char_run(char::is_whitespace));
2125
        assert!(Some((mk(b"xyz"), false)) == t.pop_front_char_run(char::is_whitespace));
2126
        assert!(t.pop_front_char_run(char::is_whitespace).is_none());
2127
2128
        let mut t = Tendril::<fmt::ASCII>::new();
2129
        assert!(t.try_push_char('x').is_ok());
2130
        assert!(t.try_push_char('\0').is_ok());
2131
        assert!(t.try_push_char('\u{a0}').is_err());
2132
        assert_eq!(b"x\0", t.as_byte_slice());
2133
    }
2134
2135
    #[test]
2136
    fn latin1() {
2137
        fn mk(x: &[u8]) -> Tendril<fmt::Latin1> {
2138
            x.to_tendril().try_reinterpret().unwrap()
2139
        }
2140
2141
        let mut t = mk(b"\xd8_\xd8");
2142
        assert_eq!(Some('Ø'), t.pop_front_char());
2143
        assert_eq!(Some('_'), t.pop_front_char());
2144
        assert_eq!(Some('Ø'), t.pop_front_char());
2145
        assert_eq!(None, t.pop_front_char());
2146
2147
        let mut t = mk(b" \t \xfe\xa7z");
2148
        assert!(Some((mk(b" \t "), true)) == t.pop_front_char_run(char::is_whitespace));
2149
        assert!(Some((mk(b"\xfe\xa7z"), false)) == t.pop_front_char_run(char::is_whitespace));
2150
        assert!(t.pop_front_char_run(char::is_whitespace).is_none());
2151
2152
        let mut t = Tendril::<fmt::Latin1>::new();
2153
        assert!(t.try_push_char('x').is_ok());
2154
        assert!(t.try_push_char('\0').is_ok());
2155
        assert!(t.try_push_char('\u{a0}').is_ok());
2156
        assert!(t.try_push_char('ő').is_err());
2157
        assert!(t.try_push_char('я').is_err());
2158
        assert!(t.try_push_char('\u{a66e}').is_err());
2159
        assert!(t.try_push_char('\u{1f4a9}').is_err());
2160
        assert_eq!(b"x\0\xa0", t.as_byte_slice());
2161
    }
2162
2163
    #[test]
2164
    fn format() {
2165
        assert_eq!("", &*format_tendril!(""));
2166
        assert_eq!(
2167
            "two and two make 4",
2168
            &*format_tendril!("two and two make {}", 2 + 2)
2169
        );
2170
    }
2171
2172
    #[test]
2173
    fn merge_shared() {
2174
        let t = "012345678901234567890123456789".to_tendril();
2175
        let a = t.subtendril(10, 20);
2176
        assert!(a.is_shared());
2177
        assert_eq!("01234567890123456789", &*a);
2178
        let mut b = t.subtendril(0, 10);
2179
        assert!(b.is_shared());
2180
        assert_eq!("0123456789", &*b);
2181
2182
        b.push_tendril(&a);
2183
        assert!(b.is_shared());
2184
        assert!(a.is_shared());
2185
        assert!(a.is_shared_with(&b));
2186
        assert!(b.is_shared_with(&a));
2187
        assert_eq!("012345678901234567890123456789", &*b);
2188
2189
        assert!(t.is_shared());
2190
        assert!(t.is_shared_with(&a));
2191
        assert!(t.is_shared_with(&b));
2192
    }
2193
2194
    #[test]
2195
    fn merge_cant_share() {
2196
        let t = "012345678901234567890123456789".to_tendril();
2197
        let mut b = t.subtendril(0, 10);
2198
        assert!(b.is_shared());
2199
        assert_eq!("0123456789", &*b);
2200
2201
        b.push_tendril(&"abcd".to_tendril());
2202
        assert!(!b.is_shared());
2203
        assert_eq!("0123456789abcd", &*b);
2204
    }
2205
2206
    #[test]
2207
    fn shared_doesnt_reserve() {
2208
        let mut t = "012345678901234567890123456789".to_tendril();
2209
        let a = t.subtendril(1, 10);
2210
2211
        assert!(t.is_shared());
2212
        t.reserve(10);
2213
        assert!(t.is_shared());
2214
2215
        let _ = a;
2216
    }
2217
2218
    #[test]
2219
    fn out_of_bounds() {
2220
        assert!("".to_tendril().try_subtendril(0, 1).is_err());
2221
        assert!("abc".to_tendril().try_subtendril(0, 4).is_err());
2222
        assert!("abc".to_tendril().try_subtendril(3, 1).is_err());
2223
        assert!("abc".to_tendril().try_subtendril(7, 1).is_err());
2224
2225
        let mut t = "".to_tendril();
2226
        assert!(t.try_pop_front(1).is_err());
2227
        assert!(t.try_pop_front(5).is_err());
2228
        assert!(t.try_pop_front(500).is_err());
2229
        assert!(t.try_pop_back(1).is_err());
2230
        assert!(t.try_pop_back(5).is_err());
2231
        assert!(t.try_pop_back(500).is_err());
2232
2233
        let mut t = "abcd".to_tendril();
2234
        assert!(t.try_pop_front(1).is_ok());
2235
        assert!(t.try_pop_front(4).is_err());
2236
        assert!(t.try_pop_front(500).is_err());
2237
        assert!(t.try_pop_back(1).is_ok());
2238
        assert!(t.try_pop_back(3).is_err());
2239
        assert!(t.try_pop_back(500).is_err());
2240
    }
2241
2242
    #[test]
2243
    fn compare() {
2244
        for &a in &[
2245
            "indiscretions",
2246
            "validity",
2247
            "hallucinogenics",
2248
            "timelessness",
2249
            "original",
2250
            "microcosms",
2251
            "boilers",
2252
            "mammoth",
2253
        ] {
2254
            for &b in &[
2255
                "intrepidly",
2256
                "frigid",
2257
                "spa",
2258
                "cardigans",
2259
                "guileful",
2260
                "evaporated",
2261
                "unenthusiastic",
2262
                "legitimate",
2263
            ] {
2264
                let ta = a.to_tendril();
2265
                let tb = b.to_tendril();
2266
2267
                assert_eq!(a.eq(b), ta.eq(&tb));
2268
                assert_eq!(a.ne(b), ta.ne(&tb));
2269
                assert_eq!(a.lt(b), ta.lt(&tb));
2270
                assert_eq!(a.le(b), ta.le(&tb));
2271
                assert_eq!(a.gt(b), ta.gt(&tb));
2272
                assert_eq!(a.ge(b), ta.ge(&tb));
2273
                assert_eq!(a.partial_cmp(b), ta.partial_cmp(&tb));
2274
                assert_eq!(a.cmp(b), ta.cmp(&tb));
2275
            }
2276
        }
2277
    }
2278
2279
    #[test]
2280
    fn extend_and_from_iterator() {
2281
        // Testing Extend<T> and FromIterator<T> for the various Ts.
2282
2283
        // Tendril<F>
2284
        let mut t = "Hello".to_tendril();
2285
        t.extend(None::<&Tendril<_>>.into_iter());
2286
        assert_eq!("Hello", &*t);
2287
        t.extend(&[", ".to_tendril(), "world".to_tendril(), "!".to_tendril()]);
2288
        assert_eq!("Hello, world!", &*t);
2289
        assert_eq!(
2290
            "Hello, world!",
2291
            &*[
2292
                "Hello".to_tendril(),
2293
                ", ".to_tendril(),
2294
                "world".to_tendril(),
2295
                "!".to_tendril()
2296
            ]
2297
            .iter()
2298
            .collect::<StrTendril>()
2299
        );
2300
2301
        // &str
2302
        let mut t = "Hello".to_tendril();
2303
        t.extend(None::<&str>.into_iter());
2304
        assert_eq!("Hello", &*t);
2305
        t.extend([", ", "world", "!"].iter().map(|&s| s));
2306
        assert_eq!("Hello, world!", &*t);
2307
        assert_eq!(
2308
            "Hello, world!",
2309
            &*["Hello", ", ", "world", "!"]
2310
                .iter()
2311
                .map(|&s| s)
2312
                .collect::<StrTendril>()
2313
        );
2314
2315
        // &[u8]
2316
        let mut t = b"Hello".to_tendril();
2317
        t.extend(None::<&[u8]>.into_iter());
2318
        assert_eq!(b"Hello", &*t);
2319
        t.extend(
2320
            [b", ".as_ref(), b"world".as_ref(), b"!".as_ref()]
2321
                .iter()
2322
                .map(|&s| s),
2323
        );
2324
        assert_eq!(b"Hello, world!", &*t);
2325
        assert_eq!(
2326
            b"Hello, world!",
2327
            &*[
2328
                b"Hello".as_ref(),
2329
                b", ".as_ref(),
2330
                b"world".as_ref(),
2331
                b"!".as_ref()
2332
            ]
2333
            .iter()
2334
            .map(|&s| s)
2335
            .collect::<ByteTendril>()
2336
        );
2337
2338
        let string = "the quick brown fox jumps over the lazy dog";
2339
        let string_expected = string.to_tendril();
2340
        let bytes = string.as_bytes();
2341
        let bytes_expected = bytes.to_tendril();
2342
2343
        // char
2344
        assert_eq!(string_expected, string.chars().collect());
2345
        let mut tendril = StrTendril::new();
2346
        tendril.extend(string.chars());
2347
        assert_eq!(string_expected, tendril);
2348
2349
        // &u8
2350
        assert_eq!(bytes_expected, bytes.iter().collect());
2351
        let mut tendril = ByteTendril::new();
2352
        tendril.extend(bytes);
2353
        assert_eq!(bytes_expected, tendril);
2354
2355
        // u8
2356
        assert_eq!(bytes_expected, bytes.iter().map(|&b| b).collect());
2357
        let mut tendril = ByteTendril::new();
2358
        tendril.extend(bytes.iter().map(|&b| b));
2359
        assert_eq!(bytes_expected, tendril);
2360
    }
2361
2362
    #[test]
2363
    fn from_str() {
2364
        use std::str::FromStr;
2365
        let t: Tendril<_> = FromStr::from_str("foo bar baz").unwrap();
2366
        assert_eq!("foo bar baz", &*t);
2367
    }
2368
2369
    #[test]
2370
    fn from_char() {
2371
        assert_eq!("o", &*StrTendril::from_char('o'));
2372
        assert_eq!("ő", &*StrTendril::from_char('ő'));
2373
        assert_eq!("\u{a66e}", &*StrTendril::from_char('\u{a66e}'));
2374
        assert_eq!("\u{1f4a9}", &*StrTendril::from_char('\u{1f4a9}'));
2375
    }
2376
2377
    #[test]
2378
    #[cfg_attr(miri, ignore)] // slow
2379
    fn read() {
2380
        fn check(x: &[u8]) {
2381
            use std::io::Cursor;
2382
            let mut t = ByteTendril::new();
2383
            assert_eq!(x.len(), Cursor::new(x).read_to_tendril(&mut t).unwrap());
2384
            assert_eq!(x, &*t);
2385
        }
2386
2387
        check(b"");
2388
        check(b"abcd");
2389
2390
        let long: Vec<u8> = iter::repeat(b'x').take(1_000_000).collect();
2391
        check(&long);
2392
    }
2393
2394
    #[test]
2395
    fn hash_map_key() {
2396
        use std::collections::HashMap;
2397
2398
        // As noted with Borrow, indexing on HashMap<StrTendril, _> is byte-based because of
2399
        // https://github.com/rust-lang/rust/issues/27108.
2400
        let mut map = HashMap::new();
2401
        map.insert("foo".to_tendril(), 1);
2402
        assert_eq!(map.get(b"foo".as_ref()), Some(&1));
2403
        assert_eq!(map.get(b"bar".as_ref()), None);
2404
2405
        let mut map = HashMap::new();
2406
        map.insert(b"foo".to_tendril(), 1);
2407
        assert_eq!(map.get(b"foo".as_ref()), Some(&1));
2408
        assert_eq!(map.get(b"bar".as_ref()), None);
2409
    }
2410
2411
    #[test]
2412
    fn atomic() {
2413
        assert_send::<Tendril<fmt::UTF8, Atomic>>();
2414
        let s: Tendril<fmt::UTF8, Atomic> = Tendril::from_slice("this is a string");
2415
        assert!(!s.is_shared());
2416
        let mut t = s.clone();
2417
        assert!(s.is_shared());
2418
        let sp = s.as_ptr() as usize;
2419
        thread::spawn(move || {
2420
            assert!(t.is_shared());
2421
            t.push_slice(" extended");
2422
            assert_eq!("this is a string extended", &*t);
2423
            assert!(t.as_ptr() as usize != sp);
2424
            assert!(!t.is_shared());
2425
        })
2426
        .join()
2427
        .unwrap();
2428
        assert!(s.is_shared());
2429
        assert_eq!("this is a string", &*s);
2430
    }
2431
2432
    #[test]
2433
    fn send() {
2434
        assert_send::<SendTendril<fmt::UTF8>>();
2435
        let s = "this is a string".to_tendril();
2436
        let t = s.clone();
2437
        let s2 = s.into_send();
2438
        thread::spawn(move || {
2439
            let s = StrTendril::from(s2);
2440
            assert!(!s.is_shared());
2441
            assert_eq!("this is a string", &*s);
2442
        })
2443
        .join()
2444
        .unwrap();
2445
        assert_eq!("this is a string", &*t);
2446
    }
2447
2448
    /// https://github.com/servo/tendril/issues/58
2449
    #[test]
2450
    fn issue_58() {
2451
        let data = "<p><i>Hello!</p>, World!</i>";
2452
        let s: Tendril<fmt::UTF8, NonAtomic> = data.into();
2453
        assert_eq!(&*s, data);
2454
        let s: Tendril<fmt::UTF8, Atomic> = s.into_send().into();
2455
        assert_eq!(&*s, data);
2456
    }
2457
2458
    #[test]
2459
    fn inline_send() {
2460
        let s = "x".to_tendril();
2461
        let t = s.clone();
2462
        let s2 = s.into_send();
2463
        thread::spawn(move || {
2464
            let s = StrTendril::from(s2);
2465
            assert!(!s.is_shared());
2466
            assert_eq!("x", &*s);
2467
        })
2468
        .join()
2469
        .unwrap();
2470
        assert_eq!("x", &*t);
2471
    }
2472
}