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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
use crate::{
    decode::Decode,
    encode::Encode,
    into_type::IntoType,
};
use std::{
    convert::TryInto,
    mem,
};

macro_rules! impl_encode_signed {
    ($ty: ty) => {
        impl Encode for $ty {
            fn encode(&self) -> Vec<u8> {
                let bits = if self.to_be_bytes()[0] & 0x80 == 0x80 {
                    0xff
                } else {
                    0x00
                };
                let mut buf = vec![bits; 32];
                buf[32 - mem::size_of::<$ty>()..].copy_from_slice(&self.to_be_bytes());
                buf
            }

            fn required_len(&self) -> u64 {
                32
            }

            fn is_dynamic() -> bool {
                false
            }
        }
    };
}

macro_rules! impl_encode_unsigned {
    ($ty: ty) => {
        impl Encode for $ty {
            fn encode(&self) -> Vec<u8> {
                let mut buf = vec![0u8; 32];
                buf[32 - mem::size_of::<$ty>()..].copy_from_slice(&self.to_be_bytes());
                buf
            }

            fn required_len(&self) -> u64 {
                32
            }

            fn is_dynamic() -> bool {
                false
            }
        }
    };
}

impl_encode_signed!(i8);
impl_encode_unsigned!(u8);
impl_encode_signed!(i16);
impl_encode_unsigned!(u16);
impl_encode_signed!(i32);
impl_encode_unsigned!(u32);
impl_encode_signed!(i64);
impl_encode_unsigned!(u64);
impl_encode_signed!(i128);
impl_encode_unsigned!(u128);

impl<'a> Decode<'a> for i8 {
    fn decode(buf: &'a [u8]) -> Self {
        buf[31] as i8
    }
}

impl<'a> Decode<'a> for u8 {
    fn decode(buf: &'a [u8]) -> Self {
        buf[31]
    }
}

impl<'a> Decode<'a> for i16 {
    fn decode(buf: &'a [u8]) -> Self {
        i16::from_be_bytes(buf[30..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for u16 {
    fn decode(buf: &'a [u8]) -> Self {
        u16::from_be_bytes(buf[30..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for i32 {
    fn decode(buf: &'a [u8]) -> Self {
        i32::from_be_bytes(buf[28..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for u32 {
    fn decode(buf: &'a [u8]) -> Self {
        u32::from_be_bytes(buf[28..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for i64 {
    fn decode(buf: &'a [u8]) -> Self {
        i64::from_be_bytes(buf[24..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for u64 {
    fn decode(buf: &'a [u8]) -> Self {
        u64::from_be_bytes(buf[24..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for i128 {
    fn decode(buf: &'a [u8]) -> Self {
        i128::from_be_bytes(buf[16..32].try_into().unwrap())
    }
}

impl<'a> Decode<'a> for u128 {
    fn decode(buf: &'a [u8]) -> Self {
        u128::from_be_bytes(buf[16..32].try_into().unwrap())
    }
}

pub struct Int24(pub [u8; 32]);
pub struct Int40(pub [u8; 32]);
pub struct Int48(pub [u8; 32]);
pub struct Int56(pub [u8; 32]);
pub struct Int72(pub [u8; 32]);
pub struct Int80(pub [u8; 32]);
pub struct Int88(pub [u8; 32]);
pub struct Int96(pub [u8; 32]);
pub struct Int104(pub [u8; 32]);
pub struct Int112(pub [u8; 32]);
pub struct Int120(pub [u8; 32]);
pub struct Int136(pub [u8; 32]);
pub struct Int144(pub [u8; 32]);
pub struct Int152(pub [u8; 32]);
pub struct Int160(pub [u8; 32]);
pub struct Int168(pub [u8; 32]);
pub struct Int176(pub [u8; 32]);
pub struct Int184(pub [u8; 32]);
pub struct Int192(pub [u8; 32]);
pub struct Int200(pub [u8; 32]);
pub struct Int208(pub [u8; 32]);
pub struct Int216(pub [u8; 32]);
pub struct Int224(pub [u8; 32]);
pub struct Int232(pub [u8; 32]);
pub struct Int240(pub [u8; 32]);
pub struct Int248(pub [u8; 32]);
pub struct Int256(pub [u8; 32]);

pub struct Uint24(pub [u8; 32]);
pub struct Uint40(pub [u8; 32]);
pub struct Uint48(pub [u8; 32]);
pub struct Uint56(pub [u8; 32]);
pub struct Uint72(pub [u8; 32]);
pub struct Uint80(pub [u8; 32]);
pub struct Uint88(pub [u8; 32]);
pub struct Uint96(pub [u8; 32]);
pub struct Uint104(pub [u8; 32]);
pub struct Uint112(pub [u8; 32]);
pub struct Uint120(pub [u8; 32]);
pub struct Uint136(pub [u8; 32]);
pub struct Uint144(pub [u8; 32]);
pub struct Uint152(pub [u8; 32]);
pub struct Uint160(pub [u8; 32]);
pub struct Uint168(pub [u8; 32]);
pub struct Uint176(pub [u8; 32]);
pub struct Uint184(pub [u8; 32]);
pub struct Uint192(pub [u8; 32]);
pub struct Uint200(pub [u8; 32]);
pub struct Uint208(pub [u8; 32]);
pub struct Uint216(pub [u8; 32]);
pub struct Uint224(pub [u8; 32]);
pub struct Uint232(pub [u8; 32]);
pub struct Uint240(pub [u8; 32]);
pub struct Uint248(pub [u8; 32]);
pub struct Uint256(pub [u8; 32]);

macro_rules! impl_encode_int {
    ($ty: ident, $expr: expr) => {
        impl Encode for $ty {
            fn encode(&self) -> Vec<u8> {
                self.0.to_vec()
            }

            fn required_len(&self) -> u64 {
                32
            }

            fn is_dynamic() -> bool {
                false
            }
        }

        impl<'a> Decode<'a> for $ty {
            fn decode(buf: &'a [u8]) -> Self {
                $ty(buf[0..32].try_into().unwrap())
            }
        }

        impl IntoType for $ty {
            fn into_type() -> String {
                $expr.to_string()
            }
        }
    };
}

impl_encode_int!(Int24, "int24");
impl_encode_int!(Uint24, "uint24");
impl_encode_int!(Int40, "int40");
impl_encode_int!(Uint40, "uint40");
impl_encode_int!(Int48, "int48");
impl_encode_int!(Uint48, "uint48");
impl_encode_int!(Int56, "int56");
impl_encode_int!(Uint56, "uint56");
impl_encode_int!(Int72, "int72");
impl_encode_int!(Uint72, "uint72");
impl_encode_int!(Int80, "int80");
impl_encode_int!(Uint80, "uint80");
impl_encode_int!(Int88, "int88");
impl_encode_int!(Uint88, "uint88");
impl_encode_int!(Int96, "int96");
impl_encode_int!(Uint96, "uint96");
impl_encode_int!(Int104, "int104");
impl_encode_int!(Uint104, "uint104");
impl_encode_int!(Int112, "int112");
impl_encode_int!(Uint112, "uint112");
impl_encode_int!(Int120, "int120");
impl_encode_int!(Uint120, "uint120");
impl_encode_int!(Int136, "int136");
impl_encode_int!(Uint136, "uint136");
impl_encode_int!(Int144, "int144");
impl_encode_int!(Uint144, "uint144");
impl_encode_int!(Int152, "int152");
impl_encode_int!(Uint152, "uint152");
impl_encode_int!(Int160, "int160");
impl_encode_int!(Uint160, "uint160");
impl_encode_int!(Int168, "int168");
impl_encode_int!(Uint168, "uint168");
impl_encode_int!(Int176, "int176");
impl_encode_int!(Uint176, "uint176");
impl_encode_int!(Int184, "int184");
impl_encode_int!(Uint184, "uint184");
impl_encode_int!(Int192, "int192");
impl_encode_int!(Uint192, "uint192");
impl_encode_int!(Int200, "int200");
impl_encode_int!(Uint200, "uint200");
impl_encode_int!(Int208, "int208");
impl_encode_int!(Uint208, "uint208");
impl_encode_int!(Int216, "int216");
impl_encode_int!(Uint216, "uint216");
impl_encode_int!(Int224, "int224");
impl_encode_int!(Uint224, "uint224");
impl_encode_int!(Int232, "int232");
impl_encode_int!(Uint232, "uint232");
impl_encode_int!(Int240, "int240");
impl_encode_int!(Uint240, "uint240");
impl_encode_int!(Int248, "int248");
impl_encode_int!(Uint248, "uint248");
impl_encode_int!(Int256, "int256");
impl_encode_int!(Uint256, "uint256");