primitive_types/
lib.rs

1// Copyright 2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Primitive types shared by Substrate and Parity Ethereum.
10//!
11//! Those are uint types `U128`, `U256` and `U512`, and fixed hash types `H160`,
12//! `H256` and `H512`, with optional serde serialization, parity-scale-codec and
13//! rlp encoding.
14
15#![cfg_attr(not(feature = "std"), no_std)]
16
17// serde_no_std leads to alloc via impl, json-schema without std requires alloc
18#[cfg(all(not(feature = "std"), any(feature = "serde_no_std", feature = "json-schema")))]
19extern crate alloc;
20
21#[cfg(feature = "fp-conversion")]
22mod fp_conversion;
23#[cfg(feature = "json-schema")]
24mod json_schema;
25
26use core::convert::TryFrom;
27use fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions};
28#[cfg(feature = "scale-info")]
29use scale_info_crate::TypeInfo;
30use uint::{construct_uint, uint_full_mul_reg};
31
32/// Error type for conversion.
33#[derive(Debug, PartialEq, Eq)]
34pub enum Error {
35	/// Overflow encountered.
36	Overflow,
37}
38
39construct_uint! {
40	/// 128-bit unsigned integer.
41	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
42	pub struct U128(2);
43}
44construct_uint! {
45	/// 256-bit unsigned integer.
46	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
47	pub struct U256(4);
48}
49construct_uint! {
50	/// 512-bits unsigned integer.
51	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
52	pub struct U512(8);
53}
54
55construct_fixed_hash! {
56	/// Fixed-size uninterpreted hash type with 16 bytes (128 bits) size.
57	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
58	pub struct H128(16);
59}
60
61construct_fixed_hash! {
62	/// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size.
63	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
64	pub struct H160(20);
65}
66construct_fixed_hash! {
67	/// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size.
68	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
69	pub struct H256(32);
70}
71construct_fixed_hash! {
72	/// Fixed-size uninterpreted hash type with 48 bytes (384 bits) size.
73	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
74	pub struct H384(48);
75}
76construct_fixed_hash! {
77	/// Fixed-size uninterpreted hash type with 64 bytes (512 bits) size.
78	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
79	pub struct H512(64);
80}
81construct_fixed_hash! {
82	/// Fixed-size uninterpreted hash type with 96 bytes (768 bits) size.
83	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
84	pub struct H768(96);
85}
86
87#[cfg(feature = "num-traits")]
88mod num_traits {
89	use super::*;
90	use impl_num_traits::impl_uint_num_traits;
91
92	impl_uint_num_traits!(U128, 2);
93	impl_uint_num_traits!(U256, 4);
94	impl_uint_num_traits!(U512, 8);
95}
96
97#[cfg(feature = "impl-serde")]
98mod serde {
99	use super::*;
100	use impl_serde::{impl_fixed_hash_serde, impl_uint_serde};
101
102	impl_uint_serde!(U128, 2);
103	impl_uint_serde!(U256, 4);
104	impl_uint_serde!(U512, 8);
105
106	impl_fixed_hash_serde!(H128, 16);
107	impl_fixed_hash_serde!(H160, 20);
108	impl_fixed_hash_serde!(H256, 32);
109	impl_fixed_hash_serde!(H384, 48);
110	impl_fixed_hash_serde!(H512, 64);
111	impl_fixed_hash_serde!(H768, 96);
112}
113
114#[cfg(feature = "impl-codec")]
115mod codec {
116	use super::*;
117	use impl_codec::{impl_fixed_hash_codec, impl_uint_codec};
118
119	impl_uint_codec!(U128, 2);
120	impl_uint_codec!(U256, 4);
121	impl_uint_codec!(U512, 8);
122
123	impl_fixed_hash_codec!(H128, 16);
124	impl_fixed_hash_codec!(H160, 20);
125	impl_fixed_hash_codec!(H256, 32);
126	impl_fixed_hash_codec!(H384, 48);
127	impl_fixed_hash_codec!(H512, 64);
128	impl_fixed_hash_codec!(H768, 96);
129}
130
131#[cfg(feature = "impl-rlp")]
132mod rlp {
133	use super::*;
134	use impl_rlp::{impl_fixed_hash_rlp, impl_uint_rlp};
135
136	impl_uint_rlp!(U128, 2);
137	impl_uint_rlp!(U256, 4);
138	impl_uint_rlp!(U512, 8);
139
140	impl_fixed_hash_rlp!(H128, 16);
141	impl_fixed_hash_rlp!(H160, 20);
142	impl_fixed_hash_rlp!(H256, 32);
143	impl_fixed_hash_rlp!(H384, 48);
144	impl_fixed_hash_rlp!(H512, 64);
145	impl_fixed_hash_rlp!(H768, 96);
146}
147
148impl_fixed_hash_conversions!(H256, H160);
149
150impl U128 {
151	/// Multiplies two 128-bit integers to produce full 256-bit integer.
152	/// Overflow is not possible.
153	#[inline(always)]
154	pub fn full_mul(self, other: U128) -> U256 {
155		U256(uint_full_mul_reg!(U128, 2, self, other))
156	}
157}
158
159impl U256 {
160	/// Multiplies two 256-bit integers to produce full 512-bit integer.
161	/// Overflow is not possible.
162	#[inline(always)]
163	pub fn full_mul(self, other: U256) -> U512 {
164		U512(uint_full_mul_reg!(U256, 4, self, other))
165	}
166}
167
168impl From<U256> for U512 {
169	fn from(value: U256) -> U512 {
170		let U256(ref arr) = value;
171		let mut ret = [0; 8];
172		ret[0] = arr[0];
173		ret[1] = arr[1];
174		ret[2] = arr[2];
175		ret[3] = arr[3];
176		U512(ret)
177	}
178}
179
180impl TryFrom<U256> for U128 {
181	type Error = Error;
182
183	fn try_from(value: U256) -> Result<U128, Error> {
184		let U256(ref arr) = value;
185		if arr[2] | arr[3] != 0 {
186			return Err(Error::Overflow)
187		}
188		let mut ret = [0; 2];
189		ret[0] = arr[0];
190		ret[1] = arr[1];
191		Ok(U128(ret))
192	}
193}
194
195impl TryFrom<U512> for U256 {
196	type Error = Error;
197
198	fn try_from(value: U512) -> Result<U256, Error> {
199		let U512(ref arr) = value;
200		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
201			return Err(Error::Overflow)
202		}
203		let mut ret = [0; 4];
204		ret[0] = arr[0];
205		ret[1] = arr[1];
206		ret[2] = arr[2];
207		ret[3] = arr[3];
208		Ok(U256(ret))
209	}
210}
211
212impl TryFrom<U512> for U128 {
213	type Error = Error;
214
215	fn try_from(value: U512) -> Result<U128, Error> {
216		let U512(ref arr) = value;
217		if arr[2] | arr[3] | arr[4] | arr[5] | arr[6] | arr[7] != 0 {
218			return Err(Error::Overflow)
219		}
220		let mut ret = [0; 2];
221		ret[0] = arr[0];
222		ret[1] = arr[1];
223		Ok(U128(ret))
224	}
225}
226
227impl From<U128> for U512 {
228	fn from(value: U128) -> U512 {
229		let U128(ref arr) = value;
230		let mut ret = [0; 8];
231		ret[0] = arr[0];
232		ret[1] = arr[1];
233		U512(ret)
234	}
235}
236
237impl From<U128> for U256 {
238	fn from(value: U128) -> U256 {
239		let U128(ref arr) = value;
240		let mut ret = [0; 4];
241		ret[0] = arr[0];
242		ret[1] = arr[1];
243		U256(ret)
244	}
245}
246
247impl<'a> From<&'a U256> for U512 {
248	fn from(value: &'a U256) -> U512 {
249		let U256(ref arr) = *value;
250		let mut ret = [0; 8];
251		ret[0] = arr[0];
252		ret[1] = arr[1];
253		ret[2] = arr[2];
254		ret[3] = arr[3];
255		U512(ret)
256	}
257}
258
259impl<'a> TryFrom<&'a U512> for U256 {
260	type Error = Error;
261
262	fn try_from(value: &'a U512) -> Result<U256, Error> {
263		let U512(ref arr) = *value;
264		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
265			return Err(Error::Overflow)
266		}
267		let mut ret = [0; 4];
268		ret[0] = arr[0];
269		ret[1] = arr[1];
270		ret[2] = arr[2];
271		ret[3] = arr[3];
272		Ok(U256(ret))
273	}
274}