dryoc/
types.rs

1use lazy_static::__Deref;
2use zeroize::{Zeroize, ZeroizeOnDrop};
3
4use crate::rng::copy_randombytes;
5
6/// A stack-allocated fixed-length byte array for working with data, with
7/// optional [Serde](https://serde.rs) features.
8#[derive(Zeroize, ZeroizeOnDrop, Debug, PartialEq, Eq, Clone)]
9pub struct StackByteArray<const LENGTH: usize>([u8; LENGTH]);
10
11/// Fixed-length byte array.
12pub trait ByteArray<const LENGTH: usize>: Bytes {
13    /// Returns a reference to the underlying fixed-length byte array.
14    fn as_array(&self) -> &[u8; LENGTH];
15}
16
17/// Arbitrary-length array of bytes.
18pub trait Bytes {
19    /// Returns a slice of the underlying bytes.
20    fn as_slice(&self) -> &[u8];
21    /// Shorthand to retrieve the underlying length of the byte array.
22    fn len(&self) -> usize;
23    /// Returns true if the array is empty.
24    fn is_empty(&self) -> bool;
25}
26
27/// Fixed-length mutable byte array.
28pub trait MutByteArray<const LENGTH: usize>: ByteArray<LENGTH> + MutBytes {
29    /// Returns a mutable reference to the underlying fixed-length byte array.
30    fn as_mut_array(&mut self) -> &mut [u8; LENGTH];
31}
32
33/// Fixed-length byte array that can be created and initialized.
34pub trait NewByteArray<const LENGTH: usize>: MutByteArray<LENGTH> + NewBytes {
35    /// Returns a new fixed-length byte array, initialized with zeroes.
36    fn new_byte_array() -> Self;
37    /// Returns a new fixed-length byte array, filled with random values.
38    fn gen() -> Self;
39}
40
41/// Arbitrary-length array of mutable bytes.
42pub trait MutBytes: Bytes {
43    /// Returns a mutable slice to the underlying bytes.
44    fn as_mut_slice(&mut self) -> &mut [u8];
45    /// Copies into the underlying slice from `other`. Panics if lengths do not
46    /// match.
47    fn copy_from_slice(&mut self, other: &[u8]);
48}
49
50/// Arbitrary-length byte array that can be created and initialized.
51pub trait NewBytes: MutBytes {
52    /// Returns an empty, unallocated, arbitrary-length byte array.
53    fn new_bytes() -> Self;
54}
55
56/// A byte array which can be resized.
57pub trait ResizableBytes {
58    /// Resizes `self` with `new_len` elements, populating new values with
59    /// `value`.
60    fn resize(&mut self, new_len: usize, value: u8);
61}
62
63impl<const LENGTH: usize> ByteArray<LENGTH> for StackByteArray<LENGTH> {
64    #[inline]
65    fn as_array(&self) -> &[u8; LENGTH] {
66        &self.0
67    }
68}
69
70impl<const LENGTH: usize> Bytes for StackByteArray<LENGTH> {
71    #[inline]
72    fn as_slice(&self) -> &[u8] {
73        &self.0
74    }
75
76    #[inline]
77    fn len(&self) -> usize {
78        self.0.len()
79    }
80
81    #[inline]
82    fn is_empty(&self) -> bool {
83        self.0.is_empty()
84    }
85}
86
87impl<const LENGTH: usize> NewBytes for StackByteArray<LENGTH> {
88    fn new_bytes() -> Self {
89        Self::default()
90    }
91}
92
93impl<const LENGTH: usize> NewByteArray<LENGTH> for StackByteArray<LENGTH> {
94    fn new_byte_array() -> Self {
95        Self::default()
96    }
97
98    /// Returns a new byte array filled with random data.
99    fn gen() -> Self {
100        let mut res = Self::default();
101        copy_randombytes(&mut res.0);
102        res
103    }
104}
105
106impl<const LENGTH: usize> MutByteArray<LENGTH> for StackByteArray<LENGTH> {
107    #[inline]
108    fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
109        &mut self.0
110    }
111}
112
113impl<const LENGTH: usize> MutBytes for StackByteArray<LENGTH> {
114    #[inline]
115    fn as_mut_slice(&mut self) -> &mut [u8] {
116        &mut self.0
117    }
118
119    fn copy_from_slice(&mut self, other: &[u8]) {
120        self.0.copy_from_slice(other)
121    }
122}
123
124impl<const LENGTH: usize> NewByteArray<LENGTH> for Vec<u8> {
125    fn new_byte_array() -> Self {
126        vec![0u8; LENGTH]
127    }
128
129    /// Returns a new byte array filled with random data.
130    fn gen() -> Self {
131        let mut res = vec![0u8; LENGTH];
132        copy_randombytes(&mut res);
133        res
134    }
135}
136
137impl<const LENGTH: usize> MutByteArray<LENGTH> for Vec<u8> {
138    #[inline]
139    fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
140        assert!(
141            self.len() >= LENGTH,
142            "invalid vec length {}, expecting at least {}",
143            self.len(),
144            LENGTH
145        );
146        let arr = self.as_ptr() as *mut [u8; LENGTH];
147        unsafe { &mut *arr }
148    }
149}
150
151impl<const LENGTH: usize> ByteArray<LENGTH> for Vec<u8> {
152    #[inline]
153    fn as_array(&self) -> &[u8; LENGTH] {
154        assert!(
155            self.len() >= LENGTH,
156            "invalid vec length {}, expecting at least {}",
157            self.len(),
158            LENGTH
159        );
160        let arr = self.as_ptr() as *const [u8; LENGTH];
161        unsafe { &*arr }
162    }
163}
164
165impl<const LENGTH: usize> NewBytes for [u8; LENGTH] {
166    fn new_bytes() -> Self {
167        [0u8; LENGTH]
168    }
169}
170
171impl<const LENGTH: usize> NewByteArray<LENGTH> for [u8; LENGTH] {
172    fn new_byte_array() -> Self {
173        [0u8; LENGTH]
174    }
175
176    /// Returns a new byte array filled with random data.
177    fn gen() -> Self {
178        let mut res = Self::new_byte_array();
179        copy_randombytes(&mut res);
180        res
181    }
182}
183
184impl<const LENGTH: usize> MutByteArray<LENGTH> for [u8; LENGTH] {
185    #[inline]
186    fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
187        self
188    }
189}
190
191impl<const LENGTH: usize> MutBytes for [u8; LENGTH] {
192    #[inline]
193    fn as_mut_slice(&mut self) -> &mut [u8] {
194        self
195    }
196
197    fn copy_from_slice(&mut self, other: &[u8]) {
198        <[u8]>::copy_from_slice(self, other)
199    }
200}
201
202impl Bytes for Vec<u8> {
203    #[inline]
204    fn as_slice(&self) -> &[u8] {
205        self.as_slice()
206    }
207
208    #[inline]
209    fn len(&self) -> usize {
210        <[u8]>::len(self)
211    }
212
213    #[inline]
214    fn is_empty(&self) -> bool {
215        <[u8]>::is_empty(self)
216    }
217}
218
219impl NewBytes for Vec<u8> {
220    fn new_bytes() -> Self {
221        vec![]
222    }
223}
224
225impl MutBytes for Vec<u8> {
226    #[inline]
227    fn as_mut_slice(&mut self) -> &mut [u8] {
228        self.as_mut_slice()
229    }
230
231    fn copy_from_slice(&mut self, other: &[u8]) {
232        <[u8]>::copy_from_slice(self, other)
233    }
234}
235
236impl ResizableBytes for Vec<u8> {
237    fn resize(&mut self, new_len: usize, value: u8) {
238        self.resize(new_len, value);
239    }
240}
241
242impl Bytes for [u8] {
243    #[inline]
244    fn as_slice(&self) -> &[u8] {
245        self
246    }
247
248    #[inline]
249    fn len(&self) -> usize {
250        <[u8]>::len(self)
251    }
252
253    #[inline]
254    fn is_empty(&self) -> bool {
255        <[u8]>::is_empty(self)
256    }
257}
258
259impl Bytes for &[u8] {
260    #[inline]
261    fn as_slice(&self) -> &[u8] {
262        self
263    }
264
265    #[inline]
266    fn len(&self) -> usize {
267        <[u8]>::len(self)
268    }
269
270    #[inline]
271    fn is_empty(&self) -> bool {
272        <[u8]>::is_empty(self)
273    }
274}
275
276impl Bytes for &mut [u8] {
277    #[inline]
278    fn as_slice(&self) -> &[u8] {
279        self
280    }
281
282    #[inline]
283    fn len(&self) -> usize {
284        <[u8]>::len(self)
285    }
286
287    #[inline]
288    fn is_empty(&self) -> bool {
289        <[u8]>::is_empty(self)
290    }
291}
292
293impl<const LENGTH: usize> Bytes for [u8; LENGTH] {
294    #[inline]
295    fn as_slice(&self) -> &[u8] {
296        self
297    }
298
299    #[inline]
300    fn len(&self) -> usize {
301        <[u8]>::len(self)
302    }
303
304    #[inline]
305    fn is_empty(&self) -> bool {
306        <[u8]>::is_empty(self)
307    }
308}
309
310#[allow(suspicious_double_ref_op)]
311impl<const LENGTH: usize> Bytes for &[u8; LENGTH] {
312    #[inline]
313    fn as_slice(&self) -> &[u8] {
314        self.deref()
315    }
316
317    #[inline]
318    fn len(&self) -> usize {
319        <[u8]>::len(self.deref())
320    }
321
322    #[inline]
323    fn is_empty(&self) -> bool {
324        <[u8]>::is_empty(self.deref())
325    }
326}
327
328impl<const LENGTH: usize> ByteArray<LENGTH> for [u8; LENGTH] {
329    #[inline]
330    fn as_array(&self) -> &[u8; LENGTH] {
331        self
332    }
333}
334
335/// Provided for convenience. Panics if the input array size doesn't match
336/// `LENGTH`.
337impl<const LENGTH: usize> ByteArray<LENGTH> for &[u8] {
338    #[inline]
339    fn as_array(&self) -> &[u8; LENGTH] {
340        assert!(
341            self.len() >= LENGTH,
342            "invalid slice length {}, expecting at least {}",
343            self.len(),
344            LENGTH
345        );
346        let arr = self.as_ptr() as *const [u8; LENGTH];
347        unsafe { &*arr }
348    }
349}
350
351impl<const LENGTH: usize> ByteArray<LENGTH> for [u8] {
352    #[inline]
353    fn as_array(&self) -> &[u8; LENGTH] {
354        assert!(
355            self.len() >= LENGTH,
356            "invalid slice length {}, expecting at least {}",
357            self.len(),
358            LENGTH
359        );
360        let arr = self.as_ptr() as *const [u8; LENGTH];
361        unsafe { &*arr }
362    }
363}
364
365impl<const LENGTH: usize> MutByteArray<LENGTH> for [u8] {
366    fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
367        assert!(
368            self.len() >= LENGTH,
369            "invalid slice length {}, expecting at least {}",
370            self.len(),
371            LENGTH
372        );
373        let arr = self.as_mut_ptr() as *mut [u8; LENGTH];
374        unsafe { &mut *arr }
375    }
376}
377
378impl MutBytes for [u8] {
379    #[inline]
380    fn as_mut_slice(&mut self) -> &mut [u8] {
381        self
382    }
383
384    fn copy_from_slice(&mut self, other: &[u8]) {
385        self.copy_from_slice(other)
386    }
387}
388
389impl<const LENGTH: usize> StackByteArray<LENGTH> {
390    /// Returns a new fixed-length stack-allocated array
391    pub fn new() -> Self {
392        Self::default()
393    }
394}
395
396impl<const LENGTH: usize> std::convert::AsRef<[u8; LENGTH]> for StackByteArray<LENGTH> {
397    fn as_ref(&self) -> &[u8; LENGTH] {
398        let arr = self.0.as_ptr() as *const [u8; LENGTH];
399        unsafe { &*arr }
400    }
401}
402
403impl<const LENGTH: usize> std::convert::AsMut<[u8; LENGTH]> for StackByteArray<LENGTH> {
404    fn as_mut(&mut self) -> &mut [u8; LENGTH] {
405        let arr = self.0.as_mut_ptr() as *mut [u8; LENGTH];
406        unsafe { &mut *arr }
407    }
408}
409
410impl<const LENGTH: usize> std::convert::AsRef<[u8]> for StackByteArray<LENGTH> {
411    fn as_ref(&self) -> &[u8] {
412        self.0.as_ref()
413    }
414}
415
416impl<const LENGTH: usize> std::convert::AsMut<[u8]> for StackByteArray<LENGTH> {
417    fn as_mut(&mut self) -> &mut [u8] {
418        self.0.as_mut()
419    }
420}
421
422impl<const LENGTH: usize> std::ops::Deref for StackByteArray<LENGTH> {
423    type Target = [u8];
424
425    fn deref(&self) -> &Self::Target {
426        &self.0
427    }
428}
429
430impl<const LENGTH: usize> std::ops::DerefMut for StackByteArray<LENGTH> {
431    fn deref_mut(&mut self) -> &mut Self::Target {
432        &mut self.0
433    }
434}
435
436impl<const LENGTH: usize> std::ops::Index<usize> for StackByteArray<LENGTH> {
437    type Output = u8;
438
439    #[inline]
440    fn index(&self, index: usize) -> &Self::Output {
441        &self.0[index]
442    }
443}
444impl<const LENGTH: usize> std::ops::IndexMut<usize> for StackByteArray<LENGTH> {
445    #[inline]
446    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
447        &mut self.0[index]
448    }
449}
450
451macro_rules! impl_index {
452    ($range:ty) => {
453        impl<const LENGTH: usize> std::ops::Index<$range> for StackByteArray<LENGTH> {
454            type Output = [u8];
455
456            #[inline]
457            fn index(&self, index: $range) -> &Self::Output {
458                &self.0[index]
459            }
460        }
461        impl<const LENGTH: usize> std::ops::IndexMut<$range> for StackByteArray<LENGTH> {
462            #[inline]
463            fn index_mut(&mut self, index: $range) -> &mut Self::Output {
464                &mut self.0[index]
465            }
466        }
467    };
468}
469
470impl_index!(std::ops::Range<usize>);
471impl_index!(std::ops::RangeFull);
472impl_index!(std::ops::RangeFrom<usize>);
473impl_index!(std::ops::RangeInclusive<usize>);
474impl_index!(std::ops::RangeTo<usize>);
475impl_index!(std::ops::RangeToInclusive<usize>);
476
477impl<const LENGTH: usize> Default for StackByteArray<LENGTH> {
478    fn default() -> Self {
479        Self([0u8; LENGTH])
480    }
481}
482
483impl<const LENGTH: usize> From<&[u8; LENGTH]> for StackByteArray<LENGTH> {
484    fn from(src: &[u8; LENGTH]) -> Self {
485        let mut arr = Self::default();
486        arr.0.copy_from_slice(src);
487        arr
488    }
489}
490
491impl<const LENGTH: usize> From<[u8; LENGTH]> for StackByteArray<LENGTH> {
492    fn from(src: [u8; LENGTH]) -> Self {
493        Self::from(&src)
494    }
495}
496
497impl<const LENGTH: usize> TryFrom<&[u8]> for StackByteArray<LENGTH> {
498    type Error = crate::error::Error;
499
500    fn try_from(src: &[u8]) -> Result<Self, Self::Error> {
501        if src.len() != LENGTH {
502            Err(dryoc_error!(format!(
503                "Invalid size: expected {} found {}",
504                LENGTH,
505                src.len()
506            )))
507        } else {
508            let mut arr = Self::default();
509            arr.0.copy_from_slice(src);
510            Ok(arr)
511        }
512    }
513}
514
515#[cfg(test)]
516mod tests {
517    use super::*;
518
519    #[test]
520    #[should_panic(expected = "invalid vec length 2, expecting at least 3")]
521    fn test_vec_as_array_out_of_bounds_panic() {
522        let vec = vec![1, 2];
523        let _ = <Vec<u8> as ByteArray<3>>::as_array(&vec)[2];
524    }
525
526    #[test]
527    fn test_vec_as_array_out_of_bounds_ok() {
528        let vec = vec![1, 2];
529        let _ = <Vec<u8> as ByteArray<2>>::as_array(&vec)[1];
530    }
531
532    #[test]
533    #[should_panic(expected = "invalid vec length 2, expecting at least 3")]
534    fn test_vec_as_mut_array_out_of_bounds_panic() {
535        let mut vec = vec![1, 2];
536        let _ = <Vec<u8> as MutByteArray<3>>::as_mut_array(&mut vec)[2];
537    }
538
539    #[test]
540    fn test_vec_as_mut_array_out_of_bounds_ok() {
541        let mut vec = vec![1, 2];
542        let _ = <Vec<u8> as MutByteArray<2>>::as_mut_array(&mut vec)[1];
543    }
544}