1use std::{
2 io::{Error, ErrorKind, Result},
3 marker::PhantomData,
4 mem,
5 ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
6 slice,
7};
8
9pub trait TryGet<T> {
11 type Output;
12
13 fn try_get(&self, index: T) -> Result<Self::Output>;
15}
16
17macro_rules! impl_slice_index {
18 ( $( $x:ty ), * ) => {
19 $(
20 impl TryGet<$x> for ByteSlice {
21 type Output = ByteSlice;
22
23 fn try_get(&self, index: $x) -> Result<ByteSlice> {
24 <[u8]>::get(self, index)
25 .map(|s| unsafe { ByteSlice::from_raw_parts(s.as_ptr(), s.len()) })
26 .ok_or_else(|| Error::new(ErrorKind::Other, "out of bounds"))
27 }
28 }
29 )*
30 };
31}
32
33impl_slice_index!(
34 Range<usize>,
35 RangeFrom<usize>,
36 RangeFull,
37 RangeInclusive<usize>,
38 RangeTo<usize>,
39 RangeToInclusive<usize>
40);
41
42impl TryGet<usize> for ByteSlice {
43 type Output = u8;
44
45 fn try_get(&self, index: usize) -> Result<u8> {
46 <[u8]>::get(self, index)
47 .cloned()
48 .ok_or_else(|| Error::new(ErrorKind::Other, "out of bounds"))
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
54pub struct ByteSlice(&'static [u8]);
55
56impl ByteSlice {
57 pub fn new() -> ByteSlice {
59 ByteSlice(&[])
60 }
61
62 pub unsafe fn from_raw_parts(data: *const u8, len: usize) -> ByteSlice {
66 ByteSlice(slice::from_raw_parts(data, len))
67 }
68
69 pub fn len(&self) -> usize {
71 self.0.len()
72 }
73
74 pub fn is_empty(&self) -> bool {
78 self.len() == 0
79 }
80
81 pub fn as_ptr(&self) -> *const u8 {
83 self.0.as_ptr()
84 }
85}
86
87impl From<&'static [u8]> for ByteSlice {
88 fn from(data: &'static [u8]) -> Self {
89 ByteSlice(data)
90 }
91}
92
93impl From<Box<[u8]>> for ByteSlice {
94 fn from(data: Box<[u8]>) -> Self {
95 let s = unsafe { ByteSlice::from_raw_parts(data.as_ptr(), data.len()) };
96 mem::forget(data);
97 s
98 }
99}
100
101impl From<Vec<u8>> for ByteSlice {
102 fn from(data: Vec<u8>) -> Self {
103 ByteSlice::from(data.into_boxed_slice())
104 }
105}
106
107impl Deref for ByteSlice {
108 type Target = [u8];
109
110 fn deref(&self) -> &'static [u8] {
111 self.0
112 }
113}
114
115impl AsRef<[u8]> for ByteSlice {
116 #[inline]
117 fn as_ref(&self) -> &[u8] {
118 &self.0
119 }
120}
121
122#[repr(C)]
123struct SafeByteSlice<'a, T: 'a> {
124 ptr: *const T,
125 len: u64,
126 phantom: PhantomData<&'a T>,
127}
128
129impl<'a, T: 'a> SafeByteSlice<'a, T> {
130 pub fn as_slice(&self) -> &[T] {
131 unsafe { slice::from_raw_parts(&*self.ptr, self.len as usize) }
132 }
133}
134
135impl<'a, T: 'a> Deref for SafeByteSlice<'a, T> {
136 type Target = [T];
137
138 fn deref(&self) -> &[T] {
139 self.as_slice()
140 }
141}