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::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	pub struct U128(2);
42}
43construct_uint! {
44	/// 256-bit unsigned integer.
45	pub struct U256(4);
46}
47construct_uint! {
48	/// 512-bits unsigned integer.
49	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
50	pub struct U512(8);
51}
52
53construct_fixed_hash! {
54	/// Fixed-size uninterpreted hash type with 16 bytes (128 bits) size.
55	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
56	pub struct H128(16);
57}
58
59construct_fixed_hash! {
60	/// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size.
61	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
62	pub struct H160(20);
63}
64construct_fixed_hash! {
65	/// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size.
66	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
67	pub struct H256(32);
68}
69construct_fixed_hash! {
70	/// Fixed-size uninterpreted hash type with 48 bytes (384 bits) size.
71	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
72	pub struct H384(48);
73}
74construct_fixed_hash! {
75	/// Fixed-size uninterpreted hash type with 64 bytes (512 bits) size.
76	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
77	pub struct H512(64);
78}
79construct_fixed_hash! {
80	/// Fixed-size uninterpreted hash type with 96 bytes (768 bits) size.
81	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
82	pub struct H768(96);
83}
84
85#[cfg(feature = "scale-info")]
86mod scale_info_impl {
87	use super::*;
88
89	impl scale_info::TypeInfo for U256 {
90		type Identity = Self;
91
92		fn type_info() -> scale_info::Type {
93			scale_info::TypeDefPrimitive::U256.into()
94		}
95	}
96
97	impl scale_info::TypeInfo for U128 {
98		type Identity = Self;
99
100		fn type_info() -> scale_info::Type {
101			scale_info::TypeDefPrimitive::U128.into()
102		}
103	}
104}
105
106#[cfg(feature = "num-traits")]
107mod num_traits {
108	use super::*;
109	use impl_num_traits::impl_uint_num_traits;
110
111	impl_uint_num_traits!(U128, 2);
112	impl_uint_num_traits!(U256, 4);
113	impl_uint_num_traits!(U512, 8);
114}
115
116#[cfg(feature = "impl-serde")]
117mod serde {
118	use super::*;
119	use impl_serde::{impl_fixed_hash_serde, impl_uint_serde};
120
121	impl_uint_serde!(U128, 2);
122	impl_uint_serde!(U256, 4);
123	impl_uint_serde!(U512, 8);
124
125	impl_fixed_hash_serde!(H128, 16);
126	impl_fixed_hash_serde!(H160, 20);
127	impl_fixed_hash_serde!(H256, 32);
128	impl_fixed_hash_serde!(H384, 48);
129	impl_fixed_hash_serde!(H512, 64);
130	impl_fixed_hash_serde!(H768, 96);
131}
132
133#[cfg(feature = "impl-codec")]
134mod codec {
135	use super::*;
136	use impl_codec::{impl_fixed_hash_codec, impl_uint_codec};
137
138	impl_uint_codec!(U128, 2);
139	impl_uint_codec!(U256, 4);
140	impl_uint_codec!(U512, 8);
141
142	impl_fixed_hash_codec!(H128, 16);
143	impl_fixed_hash_codec!(H160, 20);
144	impl_fixed_hash_codec!(H256, 32);
145	impl_fixed_hash_codec!(H384, 48);
146	impl_fixed_hash_codec!(H512, 64);
147	impl_fixed_hash_codec!(H768, 96);
148}
149
150#[cfg(feature = "impl-rlp")]
151mod rlp {
152	use super::*;
153	use impl_rlp::{impl_fixed_hash_rlp, impl_uint_rlp};
154
155	impl_uint_rlp!(U128, 2);
156	impl_uint_rlp!(U256, 4);
157	impl_uint_rlp!(U512, 8);
158
159	impl_fixed_hash_rlp!(H128, 16);
160	impl_fixed_hash_rlp!(H160, 20);
161	impl_fixed_hash_rlp!(H256, 32);
162	impl_fixed_hash_rlp!(H384, 48);
163	impl_fixed_hash_rlp!(H512, 64);
164	impl_fixed_hash_rlp!(H768, 96);
165}
166
167impl_fixed_hash_conversions!(H256, H160);
168
169impl U128 {
170	/// Multiplies two 128-bit integers to produce full 256-bit integer.
171	/// Overflow is not possible.
172	#[inline(always)]
173	pub fn full_mul(self, other: U128) -> U256 {
174		U256(uint_full_mul_reg!(U128, 2, self, other))
175	}
176}
177
178impl U256 {
179	/// Multiplies two 256-bit integers to produce full 512-bit integer.
180	/// Overflow is not possible.
181	#[inline(always)]
182	pub fn full_mul(self, other: U256) -> U512 {
183		U512(uint_full_mul_reg!(U256, 4, self, other))
184	}
185}
186
187impl From<U256> for U512 {
188	fn from(value: U256) -> U512 {
189		let U256(ref arr) = value;
190		let mut ret = [0; 8];
191		ret[0] = arr[0];
192		ret[1] = arr[1];
193		ret[2] = arr[2];
194		ret[3] = arr[3];
195		U512(ret)
196	}
197}
198
199impl TryFrom<U256> for U128 {
200	type Error = Error;
201
202	fn try_from(value: U256) -> Result<U128, Error> {
203		let U256(ref arr) = value;
204		if arr[2] | arr[3] != 0 {
205			return Err(Error::Overflow)
206		}
207		let mut ret = [0; 2];
208		ret[0] = arr[0];
209		ret[1] = arr[1];
210		Ok(U128(ret))
211	}
212}
213
214impl TryFrom<U512> for U256 {
215	type Error = Error;
216
217	fn try_from(value: U512) -> Result<U256, Error> {
218		let U512(ref arr) = value;
219		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
220			return Err(Error::Overflow)
221		}
222		let mut ret = [0; 4];
223		ret[0] = arr[0];
224		ret[1] = arr[1];
225		ret[2] = arr[2];
226		ret[3] = arr[3];
227		Ok(U256(ret))
228	}
229}
230
231impl TryFrom<U512> for U128 {
232	type Error = Error;
233
234	fn try_from(value: U512) -> Result<U128, Error> {
235		let U512(ref arr) = value;
236		if arr[2] | arr[3] | arr[4] | arr[5] | arr[6] | arr[7] != 0 {
237			return Err(Error::Overflow)
238		}
239		let mut ret = [0; 2];
240		ret[0] = arr[0];
241		ret[1] = arr[1];
242		Ok(U128(ret))
243	}
244}
245
246impl From<U128> for U512 {
247	fn from(value: U128) -> U512 {
248		let U128(ref arr) = value;
249		let mut ret = [0; 8];
250		ret[0] = arr[0];
251		ret[1] = arr[1];
252		U512(ret)
253	}
254}
255
256impl From<U128> for U256 {
257	fn from(value: U128) -> U256 {
258		let U128(ref arr) = value;
259		let mut ret = [0; 4];
260		ret[0] = arr[0];
261		ret[1] = arr[1];
262		U256(ret)
263	}
264}
265
266impl<'a> From<&'a U256> for U512 {
267	fn from(value: &'a U256) -> U512 {
268		let U256(ref arr) = *value;
269		let mut ret = [0; 8];
270		ret[0] = arr[0];
271		ret[1] = arr[1];
272		ret[2] = arr[2];
273		ret[3] = arr[3];
274		U512(ret)
275	}
276}
277
278impl<'a> TryFrom<&'a U512> for U256 {
279	type Error = Error;
280
281	fn try_from(value: &'a U512) -> Result<U256, Error> {
282		let U512(ref arr) = *value;
283		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
284			return Err(Error::Overflow)
285		}
286		let mut ret = [0; 4];
287		ret[0] = arr[0];
288		ret[1] = arr[1];
289		ret[2] = arr[2];
290		ret[3] = arr[3];
291		Ok(U256(ret))
292	}
293}