1#[cfg(feature = "bytes_1")]
7mod slice_bytes;
8
9#[cfg(not(feature = "bytes_1"))]
11mod slice_default;
12
13use std::{
14 path::{Path, PathBuf},
15 sync::Arc,
16};
17
18#[cfg(not(feature = "bytes_1"))]
19pub use slice_default::{Builder, Slice};
20
21#[cfg(feature = "bytes_1")]
22pub use slice_bytes::{Builder, Slice};
23
24impl AsRef<[u8]> for Slice {
25 fn as_ref(&self) -> &[u8] {
26 &self.0
27 }
28}
29
30impl From<&[u8]> for Slice {
31 fn from(value: &[u8]) -> Self {
32 #[cfg(not(feature = "bytes_1"))]
33 {
34 Self(byteview::ByteView::new(value))
35 }
36
37 #[cfg(feature = "bytes_1")]
38 {
39 Self(bytes::Bytes::from(value.to_vec()))
40 }
41 }
42}
43
44impl From<Arc<[u8]>> for Slice {
45 fn from(value: Arc<[u8]>) -> Self {
46 Self::from(&*value)
47 }
48}
49
50impl From<&Vec<u8>> for Slice {
51 fn from(value: &Vec<u8>) -> Self {
52 Self::from(value.as_slice())
53 }
54}
55
56impl From<&str> for Slice {
57 fn from(value: &str) -> Self {
58 Self::from(value.as_bytes())
59 }
60}
61
62impl From<&String> for Slice {
63 fn from(value: &String) -> Self {
64 Self::from(value.as_str())
65 }
66}
67
68impl From<&Path> for Slice {
69 fn from(value: &Path) -> Self {
70 Self::from(value.as_os_str().as_encoded_bytes())
71 }
72}
73
74impl From<PathBuf> for Slice {
75 fn from(value: PathBuf) -> Self {
76 Self::from(value.as_os_str().as_encoded_bytes())
77 }
78}
79
80impl From<Arc<str>> for Slice {
81 fn from(value: Arc<str>) -> Self {
82 Self::from(&*value)
83 }
84}
85
86impl<const N: usize> From<[u8; N]> for Slice {
87 fn from(value: [u8; N]) -> Self {
88 Self::from(value.as_slice())
89 }
90}
91
92impl<const N: usize> From<&[u8; N]> for Slice {
93 fn from(value: &[u8; N]) -> Self {
94 Self::from(value.as_slice())
95 }
96}
97
98impl FromIterator<u8> for Slice {
99 fn from_iter<T>(iter: T) -> Self
100 where
101 T: IntoIterator<Item = u8>,
102 {
103 Vec::from_iter(iter).into()
104 }
105}
106
107impl std::ops::Deref for Slice {
108 type Target = [u8];
109
110 fn deref(&self) -> &Self::Target {
111 self.as_ref()
112 }
113}
114
115impl std::borrow::Borrow<[u8]> for Slice {
116 fn borrow(&self) -> &[u8] {
117 self
118 }
119}
120
121impl<T> PartialEq<T> for Slice
122where
123 T: AsRef<[u8]>,
124{
125 fn eq(&self, other: &T) -> bool {
126 self.as_ref() == other.as_ref()
127 }
128}
129
130impl PartialEq<Slice> for &[u8] {
131 fn eq(&self, other: &Slice) -> bool {
132 *self == other.as_ref()
133 }
134}
135
136impl<T> PartialOrd<T> for Slice
137where
138 T: AsRef<[u8]>,
139{
140 fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
141 self.as_ref().partial_cmp(other.as_ref())
142 }
143}
144
145impl PartialOrd<Slice> for &[u8] {
146 fn partial_cmp(&self, other: &Slice) -> Option<std::cmp::Ordering> {
147 (*self).partial_cmp(other.as_ref())
148 }
149}
150
151#[cfg(test)]
152#[allow(clippy::expect_used)]
153mod tests {
154 use super::Slice;
155 use std::{fmt::Debug, sync::Arc};
156 use test_log::test;
157
158 fn assert_slice_handles<T>(v: T)
159 where
160 T: Clone + Debug,
161 Slice: From<T> + PartialEq<T> + PartialOrd<T>,
162 {
163 let slice: Slice = v.clone().into();
165 assert_eq!(slice, v, "slice_arc: {slice:?}, v: {v:?}");
166 assert!(slice >= v, "slice_arc: {slice:?}, v: {v:?}");
167 }
168
169 #[test]
170 fn slice_empty() {
171 assert_eq!(Slice::empty(), []);
172 }
173
174 #[test]
175 fn slice_fuse_empty() {
176 let bytes = Slice::fused(&[], &[]);
177 assert_eq!(&*bytes, &[] as &[u8]);
178 }
179
180 #[test]
181 fn slice_fuse_one() {
182 let bytes = Slice::fused(b"abc", &[]);
183 assert_eq!(&*bytes, b"abc");
184 }
185
186 #[test]
187 fn slice_fuse_two() {
188 let bytes = Slice::fused(b"abc", b"def");
189 assert_eq!(&*bytes, b"abcdef");
190 }
191
192 #[test]
193 #[allow(unsafe_code)]
194 fn slice_with_size() {
195 assert_eq!(
196 &*unsafe {
197 let mut b = Slice::builder_unzeroed(5);
198 b.fill(0);
199 b.freeze()
200 },
201 [0; 5],
202 );
203 assert_eq!(
204 &*unsafe {
205 let mut b = Slice::builder_unzeroed(50);
206 b.fill(0);
207 b.freeze()
208 },
209 [0; 50],
210 );
211 assert_eq!(
212 &*unsafe {
213 let mut b = Slice::builder_unzeroed(50);
214 b.fill(77);
215 b.freeze()
216 },
217 [77; 50],
218 );
219 }
220
221 #[test]
223 fn test_slice_instantiation() {
224 assert_slice_handles::<&[u8]>(&[1, 2, 3, 4]);
226 assert_slice_handles::<Arc<[u8]>>(Arc::new([1, 2, 3, 4]));
228 assert_slice_handles::<Vec<u8>>(vec![1, 2, 3, 4]);
230 assert_slice_handles::<&str>("hello");
232 assert_slice_handles::<String>("hello".to_string());
234 assert_slice_handles::<[u8; 4]>([1, 2, 3, 4]);
236
237 let slice = Slice::from_iter(vec![1, 2, 3, 4]);
240 assert_eq!(slice, vec![1, 2, 3, 4]);
241
242 let arc_str: Arc<str> = Arc::from("hello");
244 let slice = Slice::from(arc_str.clone());
245 assert_eq!(slice.as_ref(), arc_str.as_bytes());
246
247 let mut reader = std::io::Cursor::new(vec![1, 2, 3, 4]);
249 let slice = Slice::from_reader(&mut reader, 4).expect("read");
250 assert_eq!(slice, vec![1, 2, 3, 4]);
251 }
252}