scsys_crypto/hash/hashes/
h160.rs

1/*
2    Appellation: h160 <module>
3    Contributors: FL03 <jo3mccain@icloud.com>
4    Description:
5        ... Summary ...
6*/
7use super::H256;
8use crate::{H160Hash, Hashable};
9
10use rand::Rng;
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, Copy, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
14pub struct H160(pub H160Hash); // big endian u256
15
16impl H160 {
17    pub fn new(data: H160Hash) -> Self {
18        Self(data)
19    }
20    pub fn generate() -> Self {
21        let mut rng = rand::thread_rng();
22        let random_bytes: Vec<u8> = (0..20).map(|_| rng.gen()).collect();
23        let mut raw_bytes = [0; 20];
24        raw_bytes.copy_from_slice(&random_bytes);
25        (&raw_bytes).into()
26    }
27}
28
29impl Hashable for H160 {
30    fn hash(&self) -> H256 {
31        (*self).into()
32    }
33}
34
35impl std::convert::From<&H160Hash> for H160 {
36    fn from(input: &H160Hash) -> H160 {
37        let mut buffer: H160Hash = [0; 20];
38        buffer[..].copy_from_slice(input);
39        H160(buffer)
40    }
41}
42
43impl std::convert::From<H160Hash> for H160 {
44    fn from(input: H160Hash) -> H160 {
45        H160(input)
46    }
47}
48
49impl std::convert::From<&H256> for H160 {
50    fn from(input: &H256) -> H160 {
51        let mut buffer: H160Hash = [0; 20];
52        buffer[..].copy_from_slice(&input.0[0..20]);
53        buffer.into()
54    }
55}
56
57impl std::convert::From<H256> for H160 {
58    fn from(input: H256) -> H160 {
59        let mut buffer: H160Hash = [0; 20];
60        buffer[..].copy_from_slice(&input.0[0..20]);
61        buffer.into()
62    }
63}
64
65impl std::fmt::Debug for H160 {
66    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
67        write!(
68            f,
69            "{:>02x}{:>02x}..{:>02x}{:>02x}",
70            &self.0[0], &self.0[1], &self.0[18], &self.0[19]
71        )
72    }
73}
74
75impl std::fmt::Display for H160 {
76    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
77        let start = if let Some(precision) = f.precision() {
78            if precision >= 40 {
79                0
80            } else {
81                20 - precision / 2
82            }
83        } else {
84            0
85        };
86        for byte_idx in start..20 {
87            write!(f, "{:>02x}", &self.0[byte_idx])?;
88        }
89        Ok(())
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn test_h160_random() {
99        let a = H160::generate();
100        let b = H160::from(crate::hash::generate_random_hash());
101        assert_ne!(a, b)
102    }
103}