1use cfg_if;
24use serde::{
25 de::{Deserializer, SeqAccess, Visitor},
26 Deserialize, Serialize, Serializer,
27};
28use std::{
29 fmt::{self, Debug, Display, Formatter},
30 string::ToString,
31};
32
33cfg_if::cfg_if! {
34 if #[cfg(features = "aligned")] {
35 use std::mem::size_of,
36 pub const ID_LEN: usize = size_of::<usize>();
38 } else {
39 pub const ID_LEN: usize = 32;
41 }
42}
43
44#[derive(Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
46pub struct Identity([u8; ID_LEN]);
47
48impl Debug for Identity {
49 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50 write!(f, "<ID: {}>", hex::encode_upper(self))
51 }
52}
53
54impl Display for Identity {
55 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
56 write!(
57 f,
58 "{}",
59 hex::encode_upper(self)
60 .as_bytes()
61 .chunks(4)
62 .map(std::str::from_utf8)
63 .collect::<Result<Vec<_>, _>>()
64 .unwrap()
65 .join("-")
66 )
67 }
68}
69
70impl Identity {
71 pub fn truncate<'vec, V: Into<&'vec Vec<u8>>>(vec: V) -> Self {
76 let vec = vec.into();
77 assert!(vec.len() >= ID_LEN);
78
79 Self(
80 vec.into_iter()
81 .enumerate()
82 .take(ID_LEN)
83 .fold([0; ID_LEN], |mut buf, (i, u)| {
84 buf[i] = *u;
85 buf
86 }),
87 )
88 }
89
90 pub fn from_bytes(buf: &[u8]) -> Self {
96 assert_eq!(buf.len(), ID_LEN);
97 Self(
98 buf.into_iter()
99 .enumerate()
100 .fold([0; ID_LEN], |mut buf, (i, u)| {
101 buf[i] = *u;
102 buf
103 }),
104 )
105 }
106
107 pub fn from_string(s: &String) -> Self {
108 let v: Vec<u8> = s
109 .split("-")
110 .map(|s| {
111 hex::decode(s).expect(
112 "Don't call from_string() on input that was not serialised by to_string()!",
113 )
114 })
115 .collect::<Vec<Vec<u8>>>()
116 .into_iter()
117 .flatten()
118 .collect();
119 Self::from_bytes(&v)
120 }
121
122 pub fn as_bytes(&self) -> &[u8] {
123 &self.0
124 }
125
126 #[cfg(feature = "digest")]
137 pub fn with_digest<'vec, V: Into<&'vec Vec<u8>>>(vec: V) -> Self {
138 use blake2::{
139 digest::{Input, VariableOutput},
140 VarBlake2b,
141 };
142
143 let mut hasher = VarBlake2b::new(ID_LEN).unwrap();
144 hasher.input(vec.into());
145 Self::truncate(&hasher.vec_result())
146 }
147
148 #[cfg(feature = "random")]
150 pub fn random() -> Self {
151 use rand::RngCore;
152 let mut rng = rand::thread_rng();
153 let mut buf = [0; ID_LEN];
154 rng.fill_bytes(&mut buf);
155 Self(buf)
156 }
157
158 pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a u8> {
160 self.0.iter()
161 }
162}
163
164impl From<[u8; ID_LEN]> for Identity {
166 fn from(i: [u8; ID_LEN]) -> Self {
167 Self(i)
168 }
169}
170
171impl From<&[u8; ID_LEN]> for Identity {
173 fn from(i: &[u8; ID_LEN]) -> Self {
174 Self(i.clone())
175 }
176}
177
178impl From<Identity> for [u8; ID_LEN] {
180 fn from(i: Identity) -> Self {
181 i.0
182 }
183}
184
185impl From<&Identity> for [u8; ID_LEN] {
187 fn from(i: &Identity) -> Self {
188 i.0.clone()
189 }
190}
191
192impl AsRef<[u8]> for Identity {
194 fn as_ref(&self) -> &[u8] {
195 &self.0
196 }
197}
198
199pub struct Iter {
201 index: usize,
202 ident: Identity,
203}
204
205impl Iterator for Iter {
206 type Item = u8;
207 fn next(&mut self) -> Option<Self::Item> {
208 let ret = self.ident.0.get(self.index).map(|byte| *byte);
209 self.index += 1;
210 ret
211 }
212}
213
214impl IntoIterator for Identity {
215 type Item = u8;
216 type IntoIter = Iter;
217 fn into_iter(self) -> Self::IntoIter {
218 Iter {
219 index: 0,
220 ident: self,
221 }
222 }
223}
224
225impl Serialize for Identity {
226 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
227 where
228 S: Serializer,
229 {
230 if ser.is_human_readable() {
231 ser.serialize_str(&self.to_string())
232 } else {
233 ser.serialize_bytes(&self.0)
234 }
235 }
236}
237
238impl<'de> Deserialize<'de> for Identity {
239 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
240 where
241 D: Deserializer<'de>,
242 {
243 use serde::de::Error;
244
245 struct IdentityVisitor;
246
247 impl IdentityVisitor {
248 fn from_str<E: Error>(v: &str) -> Result<Identity, E> {
249 let v: Vec<u8> = v
250 .split("-")
251 .map(|s| hex::decode(s).map_err(|e| E::custom(e)))
252 .collect::<Result<Vec<Vec<u8>>, E>>()?
255 .into_iter()
256 .flatten()
257 .collect();
258
259 Self::from_bytes(&v)
260 }
261
262 fn from_bytes<E: Error, V: AsRef<[u8]>>(v: V) -> Result<Identity, E> {
263 let v = v.as_ref();
264 if v.len() != ID_LEN {
265 return Err(E::custom(format!(
266 "Expected {} bytes, got {}",
267 ID_LEN,
268 v.len()
269 )));
270 }
271
272 Ok(Identity(v.iter().enumerate().take(ID_LEN).fold(
273 [0; ID_LEN],
274 |mut buf, (i, u)| {
275 buf[i] = *u;
276 buf
277 },
278 )))
279 }
280 }
281
282 impl<'de> Visitor<'de> for IdentityVisitor {
283 type Value = Identity;
284
285 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
286 write!(
287 f,
288 "Either a {l} byte array or a hex string representing {l} bytes",
289 l = ID_LEN
290 )
291 }
292
293 fn visit_borrowed_str<E: Error>(self, v: &'de str) -> Result<Self::Value, E> {
294 Self::from_str(v)
295 }
296
297 fn visit_string<E: Error>(self, v: String) -> Result<Self::Value, E> {
298 Self::from_str(&v)
299 }
300
301 fn visit_borrowed_bytes<E: Error>(self, v: &'de [u8]) -> Result<Self::Value, E> {
302 Self::from_bytes(v)
303 }
304
305 fn visit_byte_buf<E: Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
306 Self::from_bytes(v)
307 }
308
309 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
310 where
311 A: SeqAccess<'de>,
312 {
313 let mut v = Vec::new();
314 while let Some(b) = seq.next_element::<u8>()? {
315 v.push(b);
316 }
317
318 Self::from_bytes(v)
319 }
320 }
321
322 if deserializer.is_human_readable() {
323 deserializer.deserialize_str(IdentityVisitor)
324 } else {
325 deserializer.deserialize_bytes(IdentityVisitor)
326 }
327 }
328}
329
330#[cfg(test)]
331mod test {
332 use super::*;
333 use bincode;
334 use serde_json;
335
336 #[test]
337 #[cfg(not(features = "aligned"))]
338 fn json_serde() {
339 let s = b"Yes, we will make total destroy.";
340 let i = Identity::truncate(&s.to_vec());
341 let v = serde_json::to_string(&i).unwrap();
342 assert_eq!(
343 v,
344 "\"5965-732C-2077-6520-7769-6C6C-206D-616B-6520-746F-7461-6C20-6465-7374-726F-792E\""
345 );
346 let i2 = serde_json::from_str(&v).unwrap();
347 assert_eq!(i, i2);
348 }
349
350 #[test]
351 #[cfg(not(features = "aligned"))]
352 fn bincode_serde() {
353 let s = b"Yes, we will make total destroy.";
354 let i = Identity::truncate(&s.to_vec());
355 let v: Vec<u8> = bincode::serialize(&i).unwrap();
356 assert_eq!(
357 v,
358 vec![
359 32, 0, 0, 0, 0, 0, 0, 0, 89, 101, 115, 44, 32, 119, 101, 32, 119, 105, 108, 108,
360 32, 109, 97, 107, 101, 32, 116, 111, 116, 97, 108, 32, 100, 101, 115, 116, 114,
361 111, 121, 46
362 ],
363 );
364 let i2 = bincode::deserialize(&v).unwrap();
365 assert_eq!(i, i2);
366 }
367
368 #[test]
369 #[cfg(features = "aligned")]
370 fn sized() {
371 assert_eq!(crate::ID_LEN, size_of::<usize>());
372 }
373
374 #[test]
376 #[cfg(not(features = "aligned"))]
377 fn sized() {
378 assert_eq!(crate::ID_LEN, 32);
379 }
380}