1use core::convert::Infallible;
16use core::ops::{Index, RangeBounds};
17#[cfg(feature = "bytes")] use bytes::{Bytes, BytesMut};
18#[cfg(feature = "std")] use std::borrow::Cow;
19#[cfg(feature = "std")] use std::vec::Vec;
20use crate::builder::ShortBuf;
21
22
23pub trait Octets: AsRef<[u8]> {
33 type Range<'a>: Octets where Self: 'a;
34
35 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_>;
42}
43
44impl<'t, T: Octets + ?Sized> Octets for &'t T {
45 type Range<'a> = <T as Octets>::Range<'t> where Self: 'a;
46
47 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
48 (*self).range(range)
49 }
50}
51
52impl Octets for [u8] {
53 type Range<'a> = &'a [u8];
54
55 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
56 self.index(
57 (range.start_bound().cloned(), range.end_bound().cloned())
58 )
59 }
60}
61
62#[cfg(feature = "std")]
63impl<'c> Octets for Cow<'c, [u8]> {
64 type Range<'a> = &'a [u8] where Self: 'a;
65
66 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
67 self.as_ref().range(range)
68 }
69}
70
71#[cfg(feature = "std")]
72impl Octets for Vec<u8> {
73 type Range<'a> = &'a [u8];
74
75 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
76 self.as_slice().range(range)
77 }
78}
79
80#[cfg(feature = "std")]
81impl Octets for std::sync::Arc<[u8]> {
82 type Range<'a> = &'a [u8];
83
84 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
85 self.as_ref().range(range)
86 }
87}
88
89#[cfg(feature = "bytes")]
90impl Octets for Bytes {
91 type Range<'a> = Bytes;
92
93 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
94 self.slice(range)
95 }
96}
97
98#[cfg(feature = "smallvec")]
99impl<A: smallvec::Array<Item = u8>> Octets for smallvec::SmallVec<A> {
100 type Range<'a> = &'a [u8] where A: 'a;
101
102 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
103 self.as_slice().range(range)
104 }
105}
106
107#[cfg(feature = "heapless")]
108impl<const N: usize> Octets for heapless::Vec<u8, N> {
109 type Range<'a> = &'a [u8] where Self: 'a;
110
111 fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
112 self.index(
113 (range.start_bound().cloned(), range.end_bound().cloned())
114 )
115 }
116}
117
118
119pub trait OctetsFrom<Source>: Sized {
130 type Error: Into<ShortBuf>;
131
132 fn try_octets_from(source: Source) -> Result<Self, Self::Error>;
134
135 fn octets_from(source: Source) -> Self
137 where Self::Error: Into<Infallible> {
138 match Self::try_octets_from(source) {
140 Ok(ok) => ok,
141 Err(_) => unreachable!()
142 }
143 }
144}
145
146impl<'a, Source: AsRef<[u8]> + 'a> OctetsFrom<&'a Source> for &'a [u8] {
147 type Error = Infallible;
148
149 fn try_octets_from(source: &'a Source) -> Result<Self, Self::Error> {
150 Ok(source.as_ref())
151 }
152}
153
154#[cfg(feature = "std")]
155impl<Source> OctetsFrom<Source> for Vec<u8>
156where
157 Self: From<Source>,
158{
159 type Error = Infallible;
160
161 fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
162 Ok(From::from(source))
163 }
164}
165
166#[cfg(feature = "bytes")]
167impl<Source> OctetsFrom<Source> for Bytes
168where
169 Self: From<Source>,
170{
171 type Error = Infallible;
172
173 fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
174 Ok(From::from(source))
175 }
176}
177
178#[cfg(feature = "bytes")]
179impl<Source> OctetsFrom<Source> for BytesMut
180where
181 Self: From<Source>,
182{
183 type Error = Infallible;
184
185 fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
186 Ok(From::from(source))
187 }
188}
189
190#[cfg(features = "smallvec")]
191impl<Source, A> OctetsFrom<Source> for smallvec::SmallVec<A>
192where
193 Source: AsRef<u8>,
194 A: Array<Item = u8>,
195{
196 type Error = Infallible;
197
198 fn try_octets_from(source: Source) -> Result<Self, Self::Infallible> {
199 Ok(smallvec::ToSmallVec::to_smallvec(source.as_ref()))
200 }
201}
202
203#[cfg(feature = "heapless")]
204impl<Source, const N: usize> OctetsFrom<Source> for heapless::Vec<u8, N>
205where
206 Source: AsRef<[u8]>,
207{
208 type Error = ShortBuf;
209
210 fn try_octets_from(source: Source) -> Result<Self, ShortBuf> {
211 heapless::Vec::from_slice(source.as_ref()).map_err(|_| ShortBuf)
212 }
213}
214
215
216pub trait OctetsInto<Target>: Sized {
230 type Error: Into<ShortBuf>;
231
232 fn try_octets_into(self) -> Result<Target, Self::Error>;
234
235 fn octets_into(self) -> Target
237 where Self::Error: Into<Infallible> {
238 match self.try_octets_into() {
239 Ok(ok) => ok,
240 Err(_) => unreachable!()
241 }
242 }
243}
244
245impl<Source, Target: OctetsFrom<Source>> OctetsInto<Target> for Source {
246 type Error = <Target as OctetsFrom<Source>>::Error;
247
248 fn try_octets_into(self) -> Result<Target, Self::Error> {
249 Target::try_octets_from(self)
250 }
251}
252
253
254#[cfg(feature = "smallvec")]
258pub type SmallOctets = smallvec::SmallVec<[u8; 24]>;
259