Coverage Report

Created: 2026-01-13 06:57

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