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