substrate_constructor/
try_fill.rs

1use std::str::FromStr;
2
3use num_bigint::{BigInt, BigUint};
4use primitive_types::H256;
5use sp_arithmetic::{PerU16, Perbill, Percent, Permill, Perquintill};
6use substrate_crypto_light::{
7    common::AccountId32,
8    ecdsa::{Public as PublicEcdsa, Signature as SignatureEcdsa},
9    ed25519::{Public as PublicEd25519, Signature as SignatureEd25519},
10    sr25519::{Public as PublicSr25519, Signature as SignatureSr25519},
11};
12
13use crate::{
14    fill_prepare::{
15        ArrayU8ToFill, EraToFill, RegularPrimitiveToFill, SequenceU8ToFill, SpecialTypeToFill,
16        UnsignedToFill,
17    },
18    traits::Unsigned,
19};
20
21pub trait TryFill {
22    fn upd_from_str(&mut self, source: &str);
23}
24
25macro_rules! primitive_str {
26    ($ty:ty, $old:tt, $source:tt) => {
27        if let Ok(value) = <$ty>::from_str($source) {
28            *$old = Some(value)
29        }
30    };
31}
32
33impl TryFill for UnsignedToFill {
34    fn upd_from_str(&mut self, source: &str) {
35        match self {
36            UnsignedToFill::U8(ref mut old) => primitive_str!(u8, old, source),
37            UnsignedToFill::U16(ref mut old) => primitive_str!(u16, old, source),
38            UnsignedToFill::U32(ref mut old) => primitive_str!(u32, old, source),
39            UnsignedToFill::U64(ref mut old) => primitive_str!(u64, old, source),
40            UnsignedToFill::U128(ref mut old) => primitive_str!(u128, old, source),
41        }
42    }
43}
44
45macro_rules! unsigned {
46    ($variant:ident, $old:tt, $source:tt) => {
47        if let Unsigned::$variant(value) = $source {
48            *$old = Some(*value)
49        }
50    };
51}
52
53macro_rules! unsigned_fit {
54    ($ty:ty, $old:tt, $source:tt) => {
55        if let Ok(value) = <$ty>::try_from($source) {
56            *$old = Some(value)
57        }
58    };
59}
60
61impl UnsignedToFill {
62    pub fn upd_from_unsigned(&mut self, source: &Unsigned) {
63        match self {
64            UnsignedToFill::U8(ref mut old) => unsigned!(U8, old, source),
65            UnsignedToFill::U16(ref mut old) => unsigned!(U16, old, source),
66            UnsignedToFill::U32(ref mut old) => unsigned!(U32, old, source),
67            UnsignedToFill::U64(ref mut old) => unsigned!(U64, old, source),
68            UnsignedToFill::U128(ref mut old) => unsigned!(U128, old, source),
69        }
70    }
71
72    #[allow(irrefutable_let_patterns)]
73    pub fn upd_from_u8(&mut self, source: u8) {
74        match self {
75            UnsignedToFill::U8(ref mut old) => unsigned_fit!(u8, old, source),
76            UnsignedToFill::U16(ref mut old) => unsigned_fit!(u16, old, source),
77            UnsignedToFill::U32(ref mut old) => unsigned_fit!(u32, old, source),
78            UnsignedToFill::U64(ref mut old) => unsigned_fit!(u64, old, source),
79            UnsignedToFill::U128(ref mut old) => unsigned_fit!(u128, old, source),
80        }
81    }
82
83    #[allow(irrefutable_let_patterns)]
84    pub fn upd_from_u32(&mut self, source: u32) {
85        match self {
86            UnsignedToFill::U8(ref mut old) => unsigned_fit!(u8, old, source),
87            UnsignedToFill::U16(ref mut old) => unsigned_fit!(u16, old, source),
88            UnsignedToFill::U32(ref mut old) => unsigned_fit!(u32, old, source),
89            UnsignedToFill::U64(ref mut old) => unsigned_fit!(u64, old, source),
90            UnsignedToFill::U128(ref mut old) => unsigned_fit!(u128, old, source),
91        }
92    }
93}
94
95impl TryFill for RegularPrimitiveToFill {
96    fn upd_from_str(&mut self, source: &str) {
97        match self {
98            RegularPrimitiveToFill::Bool(ref mut old) => primitive_str!(bool, old, source),
99            RegularPrimitiveToFill::Char(ref mut old) => primitive_str!(char, old, source),
100            RegularPrimitiveToFill::I8(ref mut old) => primitive_str!(i8, old, source),
101            RegularPrimitiveToFill::I16(ref mut old) => primitive_str!(i16, old, source),
102            RegularPrimitiveToFill::I32(ref mut old) => primitive_str!(i32, old, source),
103            RegularPrimitiveToFill::I64(ref mut old) => primitive_str!(i64, old, source),
104            RegularPrimitiveToFill::I128(ref mut old) => primitive_str!(i128, old, source),
105            RegularPrimitiveToFill::I256(ref mut old) => primitive_str!(BigInt, old, source),
106            RegularPrimitiveToFill::Str(ref mut old) => source.clone_into(old),
107            RegularPrimitiveToFill::U256(ref mut old) => primitive_str!(BigUint, old, source),
108        }
109    }
110}
111
112macro_rules! array_from_hex {
113    ($ty:expr, $old:tt, $source:tt) => {
114        if let Ok(value) = hex::decode($source) {
115            if let Ok(array) = value.try_into() {
116                *$old = Some($ty(array))
117            }
118        }
119    };
120}
121
122macro_rules! perthing_from_str {
123    ($ty:ty, $inner_ty:ty, $old:tt, $source:tt) => {
124        if let Ok(parts) = <$inner_ty>::from_str($source) {
125            *$old = Some(<$ty>::from_parts(parts))
126        }
127    };
128}
129
130impl TryFill for SpecialTypeToFill {
131    fn upd_from_str(&mut self, source: &str) {
132        match self {
133            SpecialTypeToFill::AccountId32(ref mut old) => {
134                array_from_hex!(AccountId32, old, source)
135            }
136            SpecialTypeToFill::Era(ref mut old) => {
137                let possibly_mortal: Vec<&str> = source.split(' ').collect();
138                if possibly_mortal.len() == 2 {
139                    if let Ok(period_entry) = u64::from_str(possibly_mortal[0]) {
140                        if let Ok(block_number_entry) = u64::from_str(possibly_mortal[1]) {
141                            *old = EraToFill::Mortal {
142                                period_entry,
143                                block_number_entry: Some(block_number_entry),
144                            };
145                        }
146                    }
147                }
148            }
149            SpecialTypeToFill::H256 {
150                hash: ref mut old,
151                specialty: _,
152            } => array_from_hex!(H256, old, source),
153            SpecialTypeToFill::PerU16 {
154                value: ref mut old,
155                is_compact: _,
156            } => perthing_from_str!(PerU16, u16, old, source),
157            SpecialTypeToFill::Perbill {
158                value: ref mut old,
159                is_compact: _,
160            } => perthing_from_str!(Perbill, u32, old, source),
161            SpecialTypeToFill::Percent {
162                value: ref mut old,
163                is_compact: _,
164            } => perthing_from_str!(Percent, u8, old, source),
165            SpecialTypeToFill::Permill {
166                value: ref mut old,
167                is_compact: _,
168            } => perthing_from_str!(Permill, u32, old, source),
169            SpecialTypeToFill::Perquintill {
170                value: ref mut old,
171                is_compact: _,
172            } => perthing_from_str!(Perquintill, u64, old, source),
173            SpecialTypeToFill::PublicEd25519(ref mut old) => {
174                array_from_hex!(PublicEd25519, old, source)
175            }
176            SpecialTypeToFill::PublicSr25519(ref mut old) => {
177                array_from_hex!(PublicSr25519, old, source)
178            }
179            SpecialTypeToFill::PublicEcdsa(ref mut old) => {
180                array_from_hex!(PublicEcdsa, old, source)
181            }
182            SpecialTypeToFill::SignatureEd25519(ref mut old) => {
183                array_from_hex!(SignatureEd25519, old, source)
184            }
185            SpecialTypeToFill::SignatureSr25519(ref mut old) => {
186                array_from_hex!(SignatureSr25519, old, source)
187            }
188            SpecialTypeToFill::SignatureEcdsa(ref mut old) => {
189                array_from_hex!(SignatureEcdsa, old, source)
190            }
191        }
192    }
193}
194
195pub trait TryBytesFill {
196    fn upd_from_single_byte(&mut self, source: &str);
197    fn upd_from_hex(&mut self, source: &str);
198    fn upd_from_utf8(&mut self, source: &str);
199}
200
201impl TryBytesFill for ArrayU8ToFill {
202    fn upd_from_single_byte(&mut self, source: &str) {
203        if let Ok(addition) = u8::from_str(source) {
204            if (self.content.len() as u32) < self.len {
205                self.content.push(addition)
206            }
207        }
208    }
209    fn upd_from_hex(&mut self, source: &str) {
210        if let Ok(value) = hex::decode(source) {
211            if value.len() as u32 == self.len {
212                self.content = value;
213            }
214        }
215    }
216    fn upd_from_utf8(&mut self, source: &str) {
217        let value = source.as_bytes().to_vec();
218        if value.len() as u32 == self.len {
219            self.content = value;
220        }
221    }
222}
223
224impl TryBytesFill for SequenceU8ToFill {
225    fn upd_from_single_byte(&mut self, source: &str) {
226        if let Ok(addition) = u8::from_str(source) {
227            self.content.push(addition)
228        }
229    }
230    fn upd_from_hex(&mut self, source: &str) {
231        if let Ok(value) = hex::decode(source) {
232            self.content = value;
233        }
234    }
235    fn upd_from_utf8(&mut self, source: &str) {
236        self.content = source.as_bytes().to_vec();
237    }
238}