primitive_types_solana/
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 And Solana.
10//!
11//! Those are uint types `U128` and `U256` and fixed hash types `H160` and
12//! `H256`, 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 fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions};
22#[cfg(feature = "scale-info")]
23use scale_info_crate::TypeInfo;
24use uint::{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}
43
44construct_fixed_hash! {
45    /// Fixed-size uninterpreted hash type with 16 bytes (128 bits) size.
46    #[cfg_attr(feature = "scale-info", derive(TypeInfo))]
47    pub struct H128(16);
48}
49
50construct_fixed_hash! {
51    /// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size.
52    #[cfg_attr(feature = "scale-info", derive(TypeInfo))]
53    pub struct H160(20);
54}
55construct_fixed_hash! {
56    /// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size.
57    #[cfg_attr(feature = "scale-info", derive(TypeInfo))]
58    pub struct H256(32);
59}
60construct_fixed_hash! {
61    /// Fixed-size uninterpreted hash type with 48 bytes (384 bits) size.
62    #[cfg_attr(feature = "scale-info", derive(TypeInfo))]
63    pub struct H384(48);
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}
70construct_fixed_hash! {
71    /// Fixed-size uninterpreted hash type with 96 bytes (768 bits) size.
72    #[cfg_attr(feature = "scale-info", derive(TypeInfo))]
73    pub struct H768(96);
74}
75
76#[cfg(feature = "num-traits")]
77mod num_traits {
78    use super::*;
79    use impl_num_traits::impl_uint_num_traits;
80
81    impl_uint_num_traits!(U128, 2);
82    impl_uint_num_traits!(U256, 4);
83}
84
85#[cfg(feature = "impl-serde")]
86mod serde {
87    use super::*;
88    use impl_serde::{impl_fixed_hash_serde, impl_uint_serde};
89
90    impl_uint_serde!(U128, 2);
91    impl_uint_serde!(U256, 4);
92
93    impl_fixed_hash_serde!(H128, 16);
94    impl_fixed_hash_serde!(H160, 20);
95    impl_fixed_hash_serde!(H256, 32);
96    impl_fixed_hash_serde!(H384, 48);
97}
98
99// true that no need std, but need to do no_std alloc than, so simplified for now
100// also no macro, but easy to create
101#[cfg(all(feature = "std", feature = "json-schema"))]
102mod json_schema {
103    use super::*;
104
105    impl schemars::JsonSchema for H160 {
106        fn schema_name() -> String {
107            "0xPrefixedHexString".to_string()
108        }
109
110        fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
111            String::json_schema(gen)
112        }
113    }
114}
115
116#[cfg(feature = "impl-codec")]
117mod codec {
118    use super::*;
119    use impl_codec::{impl_fixed_hash_codec, impl_uint_codec};
120
121    impl_uint_codec!(U128, 2);
122    impl_uint_codec!(U256, 4);
123
124    impl_fixed_hash_codec!(H128, 16);
125    impl_fixed_hash_codec!(H160, 20);
126    impl_fixed_hash_codec!(H256, 32);
127    impl_fixed_hash_codec!(H384, 48);
128}
129
130#[cfg(feature = "impl-rlp")]
131mod rlp {
132    use super::*;
133    use impl_rlp::{impl_fixed_hash_rlp, impl_uint_rlp};
134
135    impl_uint_rlp!(U128, 2);
136    impl_uint_rlp!(U256, 4);
137
138    impl_fixed_hash_rlp!(H128, 16);
139    impl_fixed_hash_rlp!(H160, 20);
140    impl_fixed_hash_rlp!(H256, 32);
141    impl_fixed_hash_rlp!(H384, 48);
142}
143
144impl_fixed_hash_conversions!(H256, H160);
145
146impl U128 {
147    /// Multiplies two 128-bit integers to produce full 256-bit integer.
148    /// Overflow is not possible.
149    #[inline(always)]
150    pub fn full_mul(self, other: U128) -> U256 {
151        U256(uint_full_mul_reg!(U128, 2, self, other))
152    }
153}
154
155impl TryFrom<U256> for U128 {
156    type Error = Error;
157
158    fn try_from(value: U256) -> Result<U128, Error> {
159        let U256(ref arr) = value;
160        if arr[2] | arr[3] != 0 {
161            return Err(Error::Overflow);
162        }
163        let mut ret = [0; 2];
164        ret[0] = arr[0];
165        ret[1] = arr[1];
166        Ok(U128(ret))
167    }
168}
169
170impl From<U128> for U256 {
171    fn from(value: U128) -> U256 {
172        let U128(ref arr) = value;
173        let mut ret = [0; 4];
174        ret[0] = arr[0];
175        ret[1] = arr[1];
176        U256(ret)
177    }
178}