1#![allow(clippy::module_name_repetitions)]
8
9use alloc::borrow::Cow;
10use core::fmt;
11use core::marker::PhantomData;
12
13use zeroize::Zeroize;
14
15pub struct Buffer<'a, T>(Cow<'a, [u8]>, PhantomData<T>);
21
22impl<T> Drop for Buffer<'_, T> {
23 fn drop(&mut self) {
24 if let Cow::Owned(b) = &mut self.0 {
25 b.zeroize();
26 }
27 }
28}
29
30impl<'a, T> Buffer<'a, T> {
31 pub(crate) fn new(owned: Vec<u8>) -> Buffer<'a, T> {
32 Buffer(Cow::Owned(owned), PhantomData)
33 }
34
35 pub(crate) fn take_from_slice(slice: &mut [u8]) -> Buffer<'a, T> {
36 let owned = slice.to_vec();
37 slice.zeroize();
38 Buffer(Cow::Owned(owned), PhantomData)
39 }
40}
41
42impl<T> fmt::Debug for Buffer<'_, T> {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
44 f.write_str("Buffer(...)")
45 }
46}
47
48impl<T> AsRef<[u8]> for Buffer<'_, T> {
49 #[inline]
50 fn as_ref(&self) -> &[u8] {
51 self.0.as_ref()
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_new() {
61 let buffer: Buffer<u8> = Buffer::new(vec![1, 2, 3]);
62 assert_eq!(buffer.as_ref(), &[1, 2, 3]);
63 }
64
65 #[test]
66 fn test_take_from_slice() {
67 let mut slice = [1, 2, 3];
68 let buffer: Buffer<u8> = Buffer::take_from_slice(&mut slice);
69 assert_eq!(buffer.as_ref(), &[1, 2, 3]);
70 assert_eq!(slice, [0, 0, 0]);
71 }
72}