1use crate::hex::hex::HashHex;
2use crate::traits::Random;
3use rand::Rng;
4use std::convert::{TryFrom, TryInto};
5
6pub type H512 = [u8; 64];
7
8impl Random for H512 {
9 fn random() -> H512 {
10 let mut rng = rand::thread_rng();
11 let mut res: [u8; 64] = [0u8; 64];
12 for i in 0..res.len() {
13 res[i] = rng.gen::<u8>();
14 }
15 res
16 }
17}
18
19impl TryFrom<HashHex> for H512 {
20 type Error = &'static str;
21 fn try_from(item: HashHex) -> Result<Self, Self::Error> {
22 match hex::decode(item.hex) {
23 Ok(bytes) => {
24 if bytes.len() != 64 {
25 return Err("Message has invalid length" as Self::Error);
26 }
27 return bytes[0..64]
28 .try_into()
29 .map_err(|_| "Unable to convert Message to H128" as Self::Error);
30 }
31 Err(_) => Err("Unable to decode message" as Self::Error),
32 }
33 }
34}
35
36impl From<H512> for HashHex {
37 fn from(item: H512) -> Self {
38 HashHex {
39 hex: hex::encode(item),
40 }
41 }
42}
43
44#[cfg(test)]
45mod test {
46 use super::*;
47 use std::any::type_name;
48
49 fn type_of<T>(_: T) -> &'static str {
50 type_name::<T>()
51 }
52
53 #[test]
54 fn test_from_string_to_H512_ok() {
55 let hex_hash = HashHex {
56 hex: String::from("b221d9dbb083a7f33428d7c2a3c3198ae925614d70210e28716ccaa7cd4ddb79b221d9dbb083a7f33428d7c2a3c3198ae925614d70210e28716ccaa7cd4ddb79"),
57 };
58 let H512: H512 = hex_hash.try_into().expect("Error");
59 assert_eq!(
60 H512,
61 [
62 178, 33, 217, 219, 176, 131, 167, 243, 52, 40, 215, 194, 163, 195, 25, 138, 233,
63 37, 97, 77, 112, 33, 14, 40, 113, 108, 202, 167, 205, 77, 219, 121, 178, 33, 217,
64 219, 176, 131, 167, 243, 52, 40, 215, 194, 163, 195, 25, 138, 233,
65 37, 97, 77, 112, 33, 14, 40, 113, 108, 202, 167, 205, 77, 219, 121
66 ],
67 "Trait does not return the expected conversion"
68 );
69 }
70
71 #[test]
72 fn test_from_string_to_H512_err() {
73 let hex_hash = HashHex {
74 hex: String::from("9a553a0x492a699dc10c7a9d429a2d7d9a553a0x492a699dc10c7a9d429a2d7de"),
75 };
76 assert!(
77 H512::try_from(hex_hash).is_err(),
78 "Returned Ok instead of Err"
79 );
80 }
81
82 #[test]
83 fn test_from_H512_to_string() {
84 let H512 = [
85 178, 33, 217, 219, 176, 131, 167, 243, 52, 40, 215, 194, 163, 195, 25, 138, 233, 37,
86 97, 77, 112, 33, 14, 40, 113, 108, 202, 167, 205, 77, 219, 121,
87 178, 33, 217, 219, 176, 131, 167, 243, 52, 40, 215, 194, 163, 195, 25, 138, 233, 37,
88 97, 77, 112, 33, 14, 40, 113, 108, 202, 167, 205, 77, 219, 121,
89 ];
90 let hex_hash: HashHex = H512.into();
91 assert_eq!(
92 hex_hash.hex,
93 String::from("b221d9dbb083a7f33428d7c2a3c3198ae925614d70210e28716ccaa7cd4ddb79b221d9dbb083a7f33428d7c2a3c3198ae925614d70210e28716ccaa7cd4ddb79"),
94 "Trait does not return the expeted conversion"
95 );
96 }
97
98 #[test]
99 fn test_from_H512_genesys() {
100 assert_eq!(type_of(H512::random()), "[u8; 64]", "Type do not match.");
101 assert_ne!(H512::random(), H512::random(), "Type do not match.");
102 }
103}