1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
use bm::{Value, ReadBackend, WriteBackend, ValueOf, Error, Index, DanglingRaw, Leak}; use primitive_types::U256; use crate::{IntoTree, FromTree, End, Intermediate, CompatibleConstruct}; use crate::utils::{mix_in_type, decode_with_type}; impl IntoTree for bool { fn into_tree<DB: WriteBackend>(&self, db: &mut DB) -> Result<ValueOf<DB::Construct>, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { match self { true => 1u8.into_tree(db), false => 0u8.into_tree(db), } } } impl FromTree for bool { fn from_tree<DB: ReadBackend>(root: &ValueOf<DB::Construct>, db: &mut DB) -> Result<Self, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { Ok(u8::from_tree(root, db)? != 0) } } macro_rules! impl_builtin_uint { ( $( $t:ty ),* ) => { $( impl IntoTree for $t { fn into_tree<DB: WriteBackend>(&self, _db: &mut DB) -> Result<ValueOf<DB::Construct>, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { let mut ret = [0u8; 32]; let bytes = self.to_le_bytes(); ret[..bytes.len()].copy_from_slice(&bytes); Ok(Value::End(End(ret))) } } impl FromTree for $t { fn from_tree<DB: ReadBackend>(root: &ValueOf<DB::Construct>, db: &mut DB) -> Result<Self, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { let raw = DanglingRaw::from_leaked(root.clone()); match raw.get(db, Index::root())?.ok_or(Error::CorruptedDatabase)? { Value::Intermediate(_) => Err(Error::CorruptedDatabase), Value::End(value) => { let mut bytes = Self::default().to_le_bytes(); let bytes_len = bytes.len(); bytes.copy_from_slice(&value.0[..bytes_len]); Ok(Self::from_le_bytes(bytes)) }, } } } )* } } impl_builtin_uint!(u8, u16, u32, u64, u128); impl IntoTree for U256 { fn into_tree<DB: WriteBackend>(&self, _db: &mut DB) -> Result<ValueOf<DB::Construct>, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { let mut ret = [0u8; 32]; self.to_little_endian(&mut ret); Ok(Value::End(End(ret))) } } impl FromTree for U256 { fn from_tree<DB: ReadBackend>(root: &ValueOf<DB::Construct>, db: &mut DB) -> Result<Self, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { let raw = DanglingRaw::from_leaked(root.clone()); match raw.get(db, Index::root())?.ok_or(Error::CorruptedDatabase)? { Value::Intermediate(_) => Err(Error::CorruptedDatabase), Value::End(value) => { Ok(U256::from_little_endian(&value.0)) }, } } } impl IntoTree for Value<Intermediate, End> { fn into_tree<DB: WriteBackend>(&self, _db: &mut DB) -> Result<ValueOf<DB::Construct>, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { Ok(self.clone()) } } impl FromTree for Value<Intermediate, End> { fn from_tree<DB: ReadBackend>(root: &ValueOf<DB::Construct>, _db: &mut DB) -> Result<Self, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { Ok(root.clone()) } } impl<T> FromTree for Option<T> where T: FromTree, { fn from_tree<DB: ReadBackend>(root: &ValueOf<DB::Construct>, db: &mut DB) -> Result<Self, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { decode_with_type(root, db, |inner, db, ty| { match ty { 0 => { <()>::from_tree(inner, db)?; Ok(None) }, 1 => Ok(Some(T::from_tree(inner, db)?)), _ => Err(Error::CorruptedDatabase), } }) } } impl<T> IntoTree for Option<T> where T: IntoTree, { fn into_tree<DB: WriteBackend>(&self, db: &mut DB) -> Result<ValueOf<DB::Construct>, Error<DB::Error>> where DB::Construct: CompatibleConstruct, { match self { None => mix_in_type(&(), db, 0), Some(value) => mix_in_type(value, db, 1), } } }