Coverage Report

Created: 2026-02-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/memchr-2.8.0/src/cow.rs
Line
Count
Source
1
use core::ops;
2
3
/// A specialized copy-on-write byte string.
4
///
5
/// The purpose of this type is to permit usage of a "borrowed or owned
6
/// byte string" in a way that keeps std/no-std compatibility. That is, in
7
/// no-std/alloc mode, this type devolves into a simple &[u8] with no owned
8
/// variant available. We can't just use a plain Cow because Cow is not in
9
/// core.
10
#[derive(Clone, Debug)]
11
pub struct CowBytes<'a>(Imp<'a>);
12
13
// N.B. We don't use alloc::borrow::Cow here since we can get away with a
14
// Box<[u8]> for our use case, which is 1/3 smaller than the Vec<u8> that
15
// a Cow<[u8]> would use.
16
#[cfg(feature = "alloc")]
17
#[derive(Clone, Debug)]
18
enum Imp<'a> {
19
    Borrowed(&'a [u8]),
20
    Owned(alloc::boxed::Box<[u8]>),
21
}
22
23
#[cfg(not(feature = "alloc"))]
24
#[derive(Clone, Debug)]
25
struct Imp<'a>(&'a [u8]);
26
27
impl<'a> ops::Deref for CowBytes<'a> {
28
    type Target = [u8];
29
30
    #[inline(always)]
31
0
    fn deref(&self) -> &[u8] {
32
0
        self.as_slice()
33
0
    }
34
}
35
36
impl<'a> CowBytes<'a> {
37
    /// Create a new borrowed CowBytes.
38
    #[inline(always)]
39
0
    pub(crate) fn new<B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> CowBytes<'a> {
40
0
        CowBytes(Imp::new(bytes.as_ref()))
41
0
    }
42
43
    /// Create a new owned CowBytes.
44
    #[cfg(feature = "alloc")]
45
    #[inline(always)]
46
0
    pub(crate) fn new_owned(
47
0
        bytes: alloc::boxed::Box<[u8]>,
48
0
    ) -> CowBytes<'static> {
49
0
        CowBytes(Imp::Owned(bytes))
50
0
    }
51
52
    /// Return a borrowed byte string, regardless of whether this is an owned
53
    /// or borrowed byte string internally.
54
    #[inline(always)]
55
0
    pub(crate) fn as_slice(&self) -> &[u8] {
56
0
        self.0.as_slice()
57
0
    }
58
59
    /// Return an owned version of this copy-on-write byte string.
60
    ///
61
    /// If this is already an owned byte string internally, then this is a
62
    /// no-op. Otherwise, the internal byte string is copied.
63
    #[cfg(feature = "alloc")]
64
    #[inline(always)]
65
0
    pub(crate) fn into_owned(self) -> CowBytes<'static> {
66
0
        match self.0 {
67
0
            Imp::Borrowed(b) => {
68
0
                CowBytes::new_owned(alloc::boxed::Box::from(b))
69
            }
70
0
            Imp::Owned(b) => CowBytes::new_owned(b),
71
        }
72
0
    }
73
}
74
75
impl<'a> Imp<'a> {
76
    #[inline(always)]
77
0
    pub fn new(bytes: &'a [u8]) -> Imp<'a> {
78
        #[cfg(feature = "alloc")]
79
        {
80
0
            Imp::Borrowed(bytes)
81
        }
82
        #[cfg(not(feature = "alloc"))]
83
        {
84
            Imp(bytes)
85
        }
86
0
    }
87
88
    #[cfg(feature = "alloc")]
89
    #[inline(always)]
90
0
    pub fn as_slice(&self) -> &[u8] {
91
        #[cfg(feature = "alloc")]
92
        {
93
0
            match self {
94
0
                Imp::Owned(ref x) => x,
95
0
                Imp::Borrowed(x) => x,
96
            }
97
        }
98
        #[cfg(not(feature = "alloc"))]
99
        {
100
            self.0
101
        }
102
0
    }
103
104
    #[cfg(not(feature = "alloc"))]
105
    #[inline(always)]
106
    pub fn as_slice(&self) -> &[u8] {
107
        self.0
108
    }
109
}