1extern crate alloc;
2
3use zeroize::{Zeroize, Zeroizing};
4
5use core::{
6 fmt::{Debug, Formatter},
7 marker::PhantomData,
8 ops::{Deref, DerefMut},
9 str::FromStr,
10};
11
12use base64ct::{Base64UrlUnpadded, Encoding, Error as DecodeError};
13use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
14
15#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
22pub struct Bytes<T = Box<[u8]>, E = Base64UrlUnpadded> {
23 buf: T,
24 cfg: PhantomData<E>,
25}
26
27impl<T: Zeroize, E> Zeroize for Bytes<T, E> {
28 fn zeroize(&mut self) {
29 self.buf.zeroize()
30 }
31}
32
33impl<T: Debug, E> Debug for Bytes<T, E> {
34 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
35 f.debug_tuple("Bytes").field(&self.buf).finish()
36 }
37}
38
39impl<T, E> Deref for Bytes<T, E> {
40 type Target = T;
41
42 fn deref(&self) -> &Self::Target {
43 &self.buf
44 }
45}
46
47impl<T, E> DerefMut for Bytes<T, E> {
48 fn deref_mut(&mut self) -> &mut Self::Target {
49 &mut self.buf
50 }
51}
52
53impl<T: AsRef<U>, U: ?Sized, E> AsRef<U> for Bytes<T, E> {
54 fn as_ref(&self) -> &U {
55 self.buf.as_ref()
56 }
57}
58
59impl<T: AsMut<U>, U: ?Sized, E> AsMut<U> for Bytes<T, E> {
60 fn as_mut(&mut self) -> &mut U {
61 self.buf.as_mut()
62 }
63}
64
65impl<T, E> From<T> for Bytes<T, E> {
66 fn from(buf: T) -> Self {
67 Self { buf, cfg: PhantomData }
68 }
69}
70
71impl<E> From<Vec<u8>> for Bytes<Box<[u8]>, E> {
72 fn from(buf: Vec<u8>) -> Self {
73 Self::from(buf.into_boxed_slice())
74 }
75}
76
77impl<E> From<Bytes<Vec<u8>, E>> for Bytes<Box<[u8]>, E> {
78 fn from(bytes: Bytes<Vec<u8>, E>) -> Self {
79 Self::from(bytes.buf.into_boxed_slice())
80 }
81}
82
83impl<E> From<Box<[u8]>> for Bytes<Vec<u8>, E> {
84 fn from(buf: Box<[u8]>) -> Self {
85 Self::from(buf.into_vec())
86 }
87}
88
89impl<E> From<Bytes<Box<[u8]>, E>> for Bytes<Vec<u8>, E> {
90 fn from(bytes: Bytes<Box<[u8]>, E>) -> Self {
91 Self::from(bytes.buf.into_vec())
92 }
93}
94
95impl<E: Encoding> FromStr for Bytes<Vec<u8>, E> {
96 type Err = DecodeError;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 Ok(Self {
100 buf: E::decode_vec(s)?,
101 cfg: PhantomData,
102 })
103 }
104}
105impl<E: Encoding> FromStr for Bytes<Box<[u8]>, E> {
106 type Err = DecodeError;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
109 Bytes::<Vec<u8>, E>::from_str(s).map(|x| x.buf.into_boxed_slice().into())
110 }
111}
112
113impl<T: AsRef<[u8]>, E: Encoding> Serialize for Bytes<T, E> {
114 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
115 let b64 = Zeroizing::from(E::encode_string(self.buf.as_ref()));
116 b64.serialize(serializer)
117 }
118}
119
120impl<'de, E: Encoding> Deserialize<'de> for Bytes<Vec<u8>, E> {
121 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
122 let enc = Zeroizing::from(String::deserialize(deserializer)?);
123 let dec = E::decode_vec(&enc).map_err(|_| D::Error::custom("invalid base64"))?;
124
125 Ok(Self { cfg: PhantomData, buf: dec })
126 }
127}
128
129impl<'de, E: Encoding> Deserialize<'de> for Bytes<Box<[u8]>, E> {
130 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
131 Bytes::<Vec<u8>, E>::deserialize(deserializer).map(|x| x.buf.into_boxed_slice().into())
132 }
133}
134
135impl<'de, E: Encoding, const N: usize> Deserialize<'de> for Bytes<[u8; N], E> {
136 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
137 let bytes = Bytes::<Vec<u8>, E>::deserialize(deserializer)?;
138 let array = <[u8; N]>::try_from(bytes.buf);
139
140 Ok(array.map_err(|_| D::Error::custom("invalid base64 length"))?.into())
141 }
142}
143
144impl<T: Default, E> Default for Bytes<T, E> {
145 fn default() -> Self {
146 Self {
147 buf: T::default(),
148 cfg: PhantomData,
149 }
150 }
151}