1pub use crate::buffer::*;
2#[cfg(not(feature = "std"))]
3use crate::rw::IoError;
4use aead::Buffer;
5use arrayvec::ArrayVec;
6use core::ops::{Deref, DerefMut};
7
8#[derive(Clone, Debug, Default)]
10pub struct ArrayBuffer<const CAP: usize>(ArrayVec<u8, CAP>);
11
12impl<const CAP: usize> ArrayBuffer<CAP> {
13 pub const fn new() -> Self {
15 Self(ArrayVec::new_const())
16 }
17
18 pub fn into_inner(self) -> ArrayVec<u8, CAP> {
19 self.0
20 }
21}
22
23impl<const CAP: usize> From<ArrayVec<u8, CAP>> for ArrayBuffer<CAP> {
24 fn from(inner: ArrayVec<u8, CAP>) -> Self {
25 Self(inner)
26 }
27}
28
29impl<const CAP: usize> Deref for ArrayBuffer<CAP> {
30 type Target = ArrayVec<u8, CAP>;
31 fn deref(&self) -> &Self::Target {
32 &self.0
33 }
34}
35
36impl<const CAP: usize> DerefMut for ArrayBuffer<CAP> {
37 fn deref_mut(&mut self) -> &mut Self::Target {
38 &mut self.0
39 }
40}
41
42impl<const CAP: usize> AsRef<[u8]> for ArrayBuffer<CAP> {
43 fn as_ref(&self) -> &[u8] {
44 self.0.as_ref()
45 }
46}
47
48impl<const CAP: usize> AsMut<[u8]> for ArrayBuffer<CAP> {
49 fn as_mut(&mut self) -> &mut [u8] {
50 self.0.as_mut()
51 }
52}
53
54impl<const CAP: usize> Buffer for ArrayBuffer<CAP> {
55 fn extend_from_slice(&mut self, other: &[u8]) -> aead::Result<()> {
56 self.0.try_extend_from_slice(other).map_err(|_| aead::Error)
57 }
58 fn truncate(&mut self, len: usize) {
59 self.0.truncate(len)
60 }
61}
62
63impl<const CAP: usize> CappedBuffer for ArrayBuffer<CAP> {
64 fn capacity(&self) -> usize {
65 self.0.capacity()
66 }
67}
68
69impl<const CAP: usize> ResizeBuffer for ArrayBuffer<CAP> {
70 fn resize_zeroed(&mut self, new_len: usize) -> Result<(), aead::Error> {
71 if new_len > self.0.capacity() {
72 return Err(aead::Error);
73 }
74 let len = self.0.len();
75 if new_len > len {
76 unsafe { self.0.set_len(new_len) };
77 self.0.as_mut_slice()[len..].fill(0);
78 } else {
79 self.0.truncate(new_len);
80 }
81 Ok(())
82 }
83}
84
85#[cfg(feature = "std")]
86impl<const CAP: usize> std::io::Write for ArrayBuffer<CAP> {
87 #[inline]
88 fn write(&mut self, data: &[u8]) -> std::io::Result<usize> {
89 let amt = std::cmp::min(data.len(), self.0.remaining_capacity());
90 self.0.try_extend_from_slice(&data[..amt]).unwrap();
91 Ok(amt)
92 }
93 #[inline]
94 fn flush(&mut self) -> std::io::Result<()> {
95 Ok(())
96 }
97}
98
99#[cfg(not(feature = "std"))]
100impl<const CAP: usize> crate::rw::Write for ArrayBuffer<CAP> {
101 type Error = IoError;
102 #[inline]
103 fn write(&mut self, data: &[u8]) -> Result<usize, Self::Error> {
104 let amt = core::cmp::min(data.len(), self.0.remaining_capacity());
105 self.0.try_extend_from_slice(&data[..amt]).unwrap();
106 Ok(amt)
107 }
108 #[inline]
109 fn flush(&mut self) -> Result<(), Self::Error> {
110 Ok(())
111 }
112 #[inline]
113 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> {
114 if self.write(data)? == data.len() {
115 Ok(())
116 } else {
117 Err(IoError::WriteZero)
118 }
119 }
120}