cita_types/
traits.rs

1// Copyright Rivtower Technologies LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::str::FromStr;
16
17use super::{clean_0x, delete_left0, pad_left0};
18use super::{Bloom, BloomInput};
19use super::{H128, H160, H256, H264, H32, H512, H520, H64};
20use super::{U128, U256, U512, U64};
21
22pub trait LowerHex {
23    fn lower_hex(&self) -> String;
24    fn lower_hex_with_0x(&self) -> String;
25}
26
27pub trait ConvertType
28where
29    Self: ::std::marker::Sized,
30{
31    fn from_unaligned(_: &str) -> Option<Self>;
32}
33
34fn convert_u8_to_char(u: u8) -> char {
35    match u {
36        u if u < 10 => (b'0' + u) as char,
37        u if (10..16).contains(&u) => (b'a' + (u - 10)) as char,
38        _ => panic!("{} not bwtween 0 and 15", u),
39    }
40}
41
42impl<'a> LowerHex for &'a [u8] {
43    fn lower_hex(&self) -> String {
44        let sz = self.len();
45        let mut s = vec![0u8 as char; sz * 2];
46        for i in 0..sz {
47            s[i * 2] = convert_u8_to_char(self[i] / 16);
48            s[i * 2 + 1] = convert_u8_to_char(self[i] % 16);
49        }
50        s.into_iter().collect()
51    }
52
53    fn lower_hex_with_0x(&self) -> String {
54        let sz = self.len();
55        let mut s = vec![0u8 as char; sz * 2 + 2];
56        s[0] = '0';
57        s[1] = 'x';
58        for i in 0..sz {
59            s[i * 2 + 2] = convert_u8_to_char(self[i] / 16);
60            s[i * 2 + 3] = convert_u8_to_char(self[i] % 16);
61        }
62        s.into_iter().collect()
63    }
64}
65
66impl LowerHex for Vec<u8> {
67    fn lower_hex(&self) -> String {
68        let s = self as &[u8];
69        s.lower_hex()
70    }
71    fn lower_hex_with_0x(&self) -> String {
72        let s = self as &[u8];
73        s.lower_hex_with_0x()
74    }
75}
76
77macro_rules! add_cita_funcs {
78    ([$( ($name:ident, $bits:expr) ),+ ,]) => {
79        add_cita_funcs!([ $( ($name, $bits) ),+ ]);
80    };
81    ([$( ($name:ident, $bits:expr) ),+]) => {
82        $( add_cita_funcs!($name, $bits); )+
83    };
84    ($name:ident, $bits:expr) => {
85        impl LowerHex for $name {
86            #[inline]
87            fn lower_hex(&self) -> String {
88                format!("{:x}", self)
89            }
90
91            #[inline]
92            fn lower_hex_with_0x(&self) -> String {
93                // TODO: https://github.com/paritytech/primitives/pull/37
94                format!("0x{:x}", self)
95            }
96        }
97
98        impl ConvertType for $name {
99            #[inline]
100            fn from_unaligned(s: &str) -> Option<Self> {
101                $name::from_str(
102                    pad_left0(
103                        delete_left0(clean_0x(s)), $bits/4usize).as_str())
104                    .ok()
105            }
106        }
107    }
108}
109
110add_cita_funcs!([
111    (Bloom, 2048),
112    (H32, 32),
113    (H64, 64),
114    (H128, 128),
115    (H160, 160),
116    (H256, 256),
117    (H264, 264),
118    (H512, 512),
119    (H520, 520),
120    (U64, 64),
121    (U128, 128),
122    (U256, 256),
123    (U512, 512),
124]);
125
126pub trait BloomTools {
127    fn from_raw(_: &[u8]) -> Self;
128    fn contains_raw(&self, _: &[u8]) -> bool;
129    fn accrue_raw(&mut self, _: &[u8]);
130}
131
132impl BloomTools for Bloom {
133    fn from_raw(raw: &[u8]) -> Bloom {
134        Bloom::from(BloomInput::Raw(raw))
135    }
136
137    fn contains_raw(&self, raw: &[u8]) -> bool {
138        self.contains_input(BloomInput::Raw(raw))
139    }
140
141    fn accrue_raw(&mut self, raw: &[u8]) {
142        self.accrue(BloomInput::Raw(raw));
143    }
144}
145
146#[cfg(test)]
147mod tests {
148    use super::convert_u8_to_char;
149    use super::U128;
150    use super::{ConvertType, LowerHex};
151
152    #[test]
153    fn test_convert_u8_to_char() {
154        let mut x = vec![0u8 as char; 2];
155        for i in 0..256 {
156            {
157                let y = x.as_mut_slice();
158                y[0] = convert_u8_to_char(i as u8 / 16);
159                y[1] = convert_u8_to_char(i as u8 % 16);
160            }
161            let s: String = x.iter().collect();
162            assert_eq!(format!("{:02x}", i), s);
163        }
164    }
165
166    #[test]
167    fn test_lower_hex_for_u8() {
168        let x = vec![0u8, 127, 255];
169        let x_str = "007fff";
170        assert_eq!(x.lower_hex(), format!("{}", x_str));
171        assert_eq!(x.lower_hex_with_0x(), format!("0x{}", x_str));
172    }
173
174    #[test]
175    fn test_lower_hex_for_uint_and_hash() {
176        let validation = vec![
177            (0u64, "0"),
178            (10u64, "a"),
179            (2432902008176639999u64, "21c3677c82b3ffff"),
180        ];
181        for (x_uint, x_str) in validation.into_iter() {
182            assert_eq!(U128::from(x_uint).lower_hex(), format!("{}", x_str));
183            assert_eq!(
184                U128::from(x_uint).lower_hex_with_0x(),
185                format!("0x{}", x_str)
186            );
187        }
188    }
189
190    #[test]
191    fn test_from_unaligned() {
192        let validation = vec![
193            (2432902008176639999u64, "0x21c3677c82b3ffff"),
194            (2432902008176639999u64, "21c3677c82b3ffff"),
195            (2432902008176639999u64, "00000000021c3677c82b3ffff"),
196            (
197                2432902008176639999u64,
198                "000000000000000000000000000000000000000021c3677c82b3ffff",
199            ),
200        ];
201        for (i, s) in validation.into_iter() {
202            assert_eq!(U128::from(i), U128::from_unaligned(s).unwrap())
203        }
204    }
205}