tetsy_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 Tetcore and Tetsy Vapory.
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#[cfg(feature = "fp-conversion")]
18mod fp_conversion;
19
20use core::convert::TryFrom;
21use tetsy_fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions};
22#[cfg(feature = "scale-info")]
23use scale_info::TypeInfo;
24use uint_crate::{construct_uint, uint_full_mul_reg};
25
26/// Error type for conversion.
27#[derive(Debug, PartialEq, Eq)]
28pub enum Error {
29	/// Overflow encountered.
30	Overflow,
31}
32
33construct_uint! {
34	/// 128-bit unsigned integer.
35	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
36	pub struct U128(2);
37}
38construct_uint! {
39	/// 256-bit unsigned integer.
40	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
41	pub struct U256(4);
42}
43construct_uint! {
44	/// 512-bits unsigned integer.
45	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
46	pub struct U512(8);
47}
48
49construct_fixed_hash! {
50	/// Fixed-size uninterpreted hash type with 16 bytes (128 bits) size.
51	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
52	pub struct H128(16);
53}
54
55construct_fixed_hash! {
56	/// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size.
57	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
58	pub struct H160(20);
59}
60construct_fixed_hash! {
61	/// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size.
62	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
63	pub struct H256(32);
64}
65construct_fixed_hash! {
66	/// Fixed-size uninterpreted hash type with 64 bytes (512 bits) size.
67	#[cfg_attr(feature = "scale-info", derive(TypeInfo))]
68	pub struct H512(64);
69}
70
71#[cfg(feature = "tetsy-num-traits")]
72mod tetsy_num_traits {
73	use super::*;
74	use tetsy_impl_num_traits::impl_uint_num_traits;
75
76	impl_uint_num_traits!(U128, 2);
77	impl_uint_num_traits!(U256, 4);
78	impl_uint_num_traits!(U512, 8);
79}
80
81#[cfg(feature = "tetsy-impl-serde")]
82mod tetsy_serde {
83	use super::*;
84	use tetsy_impl_serde::{impl_fixed_hash_serde, impl_uint_serde};
85
86	impl_uint_serde!(U128, 2);
87	impl_uint_serde!(U256, 4);
88	impl_uint_serde!(U512, 8);
89
90	impl_fixed_hash_serde!(H128, 16);
91	impl_fixed_hash_serde!(H160, 20);
92	impl_fixed_hash_serde!(H256, 32);
93	impl_fixed_hash_serde!(H512, 64);
94}
95
96#[cfg(feature = "tetsy-impl-codec")]
97mod tetsy_codec {
98	use super::*;
99	use tetsy_impl_codec::{impl_fixed_hash_codec, impl_uint_codec};
100
101	impl_uint_codec!(U128, 2);
102	impl_uint_codec!(U256, 4);
103	impl_uint_codec!(U512, 8);
104
105	impl_fixed_hash_codec!(H128, 16);
106	impl_fixed_hash_codec!(H160, 20);
107	impl_fixed_hash_codec!(H256, 32);
108	impl_fixed_hash_codec!(H512, 64);
109}
110
111#[cfg(feature = "tetsy-impl-rlp")]
112mod tetsy_rlp {
113	use super::*;
114	use tetsy_impl_rlp::{impl_fixed_hash_rlp, impl_uint_rlp};
115
116	impl_uint_rlp!(U128, 2);
117	impl_uint_rlp!(U256, 4);
118	impl_uint_rlp!(U512, 8);
119
120	impl_fixed_hash_rlp!(H128, 16);
121	impl_fixed_hash_rlp!(H160, 20);
122	impl_fixed_hash_rlp!(H256, 32);
123	impl_fixed_hash_rlp!(H512, 64);
124}
125
126impl_fixed_hash_conversions!(H256, H160);
127
128impl U256 {
129	/// Multiplies two 256-bit integers to produce full 512-bit integer
130	/// No overflow possible
131	#[inline(always)]
132	pub fn full_mul(self, other: U256) -> U512 {
133		U512(uint_full_mul_reg!(U256, 4, self, other))
134	}
135}
136
137impl From<U256> for U512 {
138	fn from(value: U256) -> U512 {
139		let U256(ref arr) = value;
140		let mut ret = [0; 8];
141		ret[0] = arr[0];
142		ret[1] = arr[1];
143		ret[2] = arr[2];
144		ret[3] = arr[3];
145		U512(ret)
146	}
147}
148
149impl TryFrom<U256> for U128 {
150	type Error = Error;
151
152	fn try_from(value: U256) -> Result<U128, Error> {
153		let U256(ref arr) = value;
154		if arr[2] | arr[3] != 0 {
155			return Err(Error::Overflow);
156		}
157		let mut ret = [0; 2];
158		ret[0] = arr[0];
159		ret[1] = arr[1];
160		Ok(U128(ret))
161	}
162}
163
164impl TryFrom<U512> for U256 {
165	type Error = Error;
166
167	fn try_from(value: U512) -> Result<U256, Error> {
168		let U512(ref arr) = value;
169		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
170			return Err(Error::Overflow);
171		}
172		let mut ret = [0; 4];
173		ret[0] = arr[0];
174		ret[1] = arr[1];
175		ret[2] = arr[2];
176		ret[3] = arr[3];
177		Ok(U256(ret))
178	}
179}
180
181impl TryFrom<U512> for U128 {
182	type Error = Error;
183
184	fn try_from(value: U512) -> Result<U128, Error> {
185		let U512(ref arr) = value;
186		if arr[2] | arr[3] | arr[4] | arr[5] | arr[6] | arr[7] != 0 {
187			return Err(Error::Overflow);
188		}
189		let mut ret = [0; 2];
190		ret[0] = arr[0];
191		ret[1] = arr[1];
192		Ok(U128(ret))
193	}
194}
195
196impl From<U128> for U512 {
197	fn from(value: U128) -> U512 {
198		let U128(ref arr) = value;
199		let mut ret = [0; 8];
200		ret[0] = arr[0];
201		ret[1] = arr[1];
202		U512(ret)
203	}
204}
205
206impl From<U128> for U256 {
207	fn from(value: U128) -> U256 {
208		let U128(ref arr) = value;
209		let mut ret = [0; 4];
210		ret[0] = arr[0];
211		ret[1] = arr[1];
212		U256(ret)
213	}
214}
215
216impl<'a> From<&'a U256> for U512 {
217	fn from(value: &'a U256) -> U512 {
218		let U256(ref arr) = *value;
219		let mut ret = [0; 8];
220		ret[0] = arr[0];
221		ret[1] = arr[1];
222		ret[2] = arr[2];
223		ret[3] = arr[3];
224		U512(ret)
225	}
226}
227
228impl<'a> TryFrom<&'a U512> for U256 {
229	type Error = Error;
230
231	fn try_from(value: &'a U512) -> Result<U256, Error> {
232		let U512(ref arr) = *value;
233		if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
234			return Err(Error::Overflow);
235		}
236		let mut ret = [0; 4];
237		ret[0] = arr[0];
238		ret[1] = arr[1];
239		ret[2] = arr[2];
240		ret[3] = arr[3];
241		Ok(U256(ret))
242	}
243}