1use alloc::boxed::Box;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17#[repr(transparent)]
18pub struct DataSlice<'a>(&'a [u8]);
19
20impl<'a> DataSlice<'a> {
21 pub fn take(self) -> &'a [u8] {
23 self.0
24 }
25
26 pub fn to_owned(&self) -> DataOwned {
28 DataOwned(self.0.into())
29 }
30}
31
32impl core::ops::Deref for DataSlice<'_> {
33 type Target = [u8];
34 fn deref(&self) -> &Self::Target {
35 self.0
36 }
37}
38
39impl<'a> From<DataSlice<'a>> for &'a [u8] {
40 fn from(value: DataSlice<'a>) -> Self {
41 value.0
42 }
43}
44
45impl<'a> From<&'a [u8]> for DataSlice<'a> {
46 fn from(value: &'a [u8]) -> Self {
47 Self(value)
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
53#[repr(transparent)]
54pub struct DataOwned(Box<[u8]>);
55
56impl DataOwned {
57 pub fn take(self) -> Box<[u8]> {
59 self.0
60 }
61}
62
63impl core::ops::Deref for DataOwned {
64 type Target = [u8];
65 fn deref(&self) -> &Self::Target {
66 &self.0
67 }
68}
69
70impl From<DataOwned> for Box<[u8]> {
71 fn from(value: DataOwned) -> Self {
72 value.0
73 }
74}
75
76impl From<Box<[u8]>> for DataOwned {
77 fn from(value: Box<[u8]>) -> Self {
78 Self(value)
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
84pub enum Data<'a> {
85 Borrowed(DataSlice<'a>),
87 Owned(DataOwned),
89}
90
91impl core::ops::Deref for Data<'_> {
92 type Target = [u8];
93 fn deref(&self) -> &Self::Target {
94 match self {
95 Self::Borrowed(data) => data.0,
96 Self::Owned(data) => &data.0,
97 }
98 }
99}
100
101impl Data<'_> {
102 pub fn into_owned<'b>(self) -> Data<'b> {
104 match self {
105 Self::Borrowed(data) => Data::Owned(data.to_owned()),
106 Self::Owned(data) => Data::Owned(data),
107 }
108 }
109}
110
111impl<'a> From<&'a [u8]> for Data<'a> {
112 fn from(value: &'a [u8]) -> Self {
113 Self::Borrowed(value.into())
114 }
115}
116
117impl From<Box<[u8]>> for Data<'_> {
118 fn from(value: Box<[u8]>) -> Self {
119 Self::Owned(value.into())
120 }
121}
122
123impl AsRef<[u8]> for Data<'_> {
124 fn as_ref(&self) -> &[u8] {
125 self
126 }
127}
128
129#[cfg(test)]
130pub(crate) mod tests {
131 use super::*;
132
133 #[test]
134 fn data_access() {
135 let _log = crate::tests::test_init_log();
136 let array = [0, 1, 2, 3];
137 let borrowed_data = Data::from(array.as_slice());
138 assert_eq!(array.as_slice(), &*borrowed_data);
139 let owned_data = borrowed_data.into_owned();
140 assert_eq!(array.as_slice(), &*owned_data);
141 let Data::Owned(owned) = owned_data else {
142 unreachable!();
143 };
144 let inner = <Box<[u8]>>::from(owned.clone());
145 assert_eq!(array.as_slice(), &*inner);
146 let owned = DataOwned::take(owned);
147 assert_eq!(array.as_slice(), &*owned);
148 let data = Data::from(owned);
149 assert_eq!(array.as_slice(), &*data);
150 let borrowed = DataSlice::from(&*data);
151 assert_eq!(array.as_slice(), &*borrowed);
152 let inner = <&[u8]>::from(borrowed.clone());
153 assert_eq!(array.as_slice(), inner);
154 let inner = borrowed.take();
155 assert_eq!(array.as_slice(), inner);
156 }
157}