Skip to main content

cw_storage_plus/
de.rs

1use std::array::TryFromSliceError;
2use std::convert::TryInto;
3
4use cosmwasm_std::{Addr, Int128, Int64, StdError, StdResult, Uint128, Uint64};
5
6use crate::int_key::IntKey;
7
8pub trait KeyDeserialize {
9    type Output: Sized;
10
11    /// The number of key elements is used for the deserialization of compound keys.
12    /// It should be equal to PrimaryKey::key().len()
13    const KEY_ELEMS: u16;
14
15    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output>;
16
17    fn from_slice(value: &[u8]) -> StdResult<Self::Output> {
18        Self::from_vec(value.to_vec())
19    }
20}
21
22impl KeyDeserialize for () {
23    type Output = ();
24
25    const KEY_ELEMS: u16 = 0;
26
27    #[inline(always)]
28    fn from_vec(_value: Vec<u8>) -> StdResult<Self::Output> {
29        Ok(())
30    }
31}
32
33impl KeyDeserialize for Vec<u8> {
34    type Output = Vec<u8>;
35
36    const KEY_ELEMS: u16 = 1;
37
38    #[inline(always)]
39    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
40        Ok(value)
41    }
42}
43
44impl KeyDeserialize for &Vec<u8> {
45    type Output = Vec<u8>;
46
47    const KEY_ELEMS: u16 = 1;
48
49    #[inline(always)]
50    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
51        Ok(value)
52    }
53}
54
55impl KeyDeserialize for &[u8] {
56    type Output = Vec<u8>;
57
58    const KEY_ELEMS: u16 = 1;
59
60    #[inline(always)]
61    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
62        Ok(value)
63    }
64}
65
66impl<const N: usize> KeyDeserialize for [u8; N] {
67    type Output = [u8; N];
68
69    const KEY_ELEMS: u16 = 1;
70
71    #[inline(always)]
72    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
73        <[u8; N]>::try_from(value).map_err(|v: Vec<_>| {
74            StdError::msg(format!(
75                "invalid_data_size: expected {}, actual {}",
76                N,
77                v.len()
78            ))
79        })
80    }
81}
82
83impl<const N: usize> KeyDeserialize for &[u8; N] {
84    type Output = [u8; N];
85
86    const KEY_ELEMS: u16 = 1;
87
88    #[inline(always)]
89    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
90        <[u8; N]>::from_vec(value)
91    }
92}
93
94impl KeyDeserialize for String {
95    type Output = String;
96
97    const KEY_ELEMS: u16 = 1;
98
99    #[inline(always)]
100    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
101        Ok(String::from_utf8(value)?)
102    }
103}
104
105impl KeyDeserialize for &String {
106    type Output = String;
107
108    const KEY_ELEMS: u16 = 1;
109
110    #[inline(always)]
111    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
112        Self::Output::from_vec(value)
113    }
114}
115
116impl KeyDeserialize for &str {
117    type Output = String;
118
119    const KEY_ELEMS: u16 = 1;
120
121    #[inline(always)]
122    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
123        Self::Output::from_vec(value)
124    }
125}
126
127impl KeyDeserialize for Addr {
128    type Output = Addr;
129
130    const KEY_ELEMS: u16 = 1;
131
132    #[inline(always)]
133    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
134        Ok(Addr::unchecked(String::from_vec(value)?))
135    }
136}
137
138impl KeyDeserialize for &Addr {
139    type Output = Addr;
140
141    const KEY_ELEMS: u16 = 1;
142
143    #[inline(always)]
144    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
145        Self::Output::from_vec(value)
146    }
147}
148
149macro_rules! integer_de {
150    (for $($t:ty),+) => {
151        $(impl KeyDeserialize for $t {
152            type Output = $t;
153
154            const KEY_ELEMS: u16 = 1;
155
156            #[inline(always)]
157            fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
158                Ok(<$t>::from_cw_bytes(value.as_slice().try_into()
159                    .map_err(|err: TryFromSliceError| StdError::msg(err.to_string()))?))
160            }
161        })*
162    }
163}
164
165integer_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, Uint64, Uint128, Int64, Int128);
166
167fn parse_length(value: &[u8]) -> StdResult<usize> {
168    Ok(u16::from_be_bytes(
169        value
170            .try_into()
171            .map_err(|_| StdError::msg("Could not read 2 byte length"))?,
172    )
173    .into())
174}
175
176/// Splits the first key from the value based on the provided number of key elements.
177/// The return value is ordered as (first_key, remainder).
178///
179fn split_first_key(key_elems: u16, value: &[u8]) -> StdResult<(Vec<u8>, &[u8])> {
180    let mut index = 0;
181    let mut first_key = Vec::new();
182
183    // Iterate over the sub keys
184    for i in 0..key_elems {
185        let len_slice = &value[index..index + 2];
186        index += 2;
187        let is_last_key = i == key_elems - 1;
188
189        if !is_last_key {
190            first_key.extend_from_slice(len_slice);
191        }
192
193        let subkey_len = parse_length(len_slice)?;
194        first_key.extend_from_slice(&value[index..index + subkey_len]);
195        index += subkey_len;
196    }
197
198    let remainder = &value[index..];
199    Ok((first_key, remainder))
200}
201
202impl<T: KeyDeserialize, U: KeyDeserialize> KeyDeserialize for (T, U) {
203    type Output = (T::Output, U::Output);
204
205    const KEY_ELEMS: u16 = T::KEY_ELEMS + U::KEY_ELEMS;
206
207    #[inline(always)]
208    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
209        let (t, u) = split_first_key(T::KEY_ELEMS, value.as_ref())?;
210        Ok((T::from_vec(t)?, U::from_vec(u.to_vec())?))
211    }
212}
213
214impl<T: KeyDeserialize, U: KeyDeserialize, V: KeyDeserialize> KeyDeserialize for (T, U, V) {
215    type Output = (T::Output, U::Output, V::Output);
216
217    const KEY_ELEMS: u16 = T::KEY_ELEMS + U::KEY_ELEMS + V::KEY_ELEMS;
218
219    #[inline(always)]
220    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
221        let (t, remainder) = split_first_key(T::KEY_ELEMS, value.as_ref())?;
222        let (u, v) = split_first_key(U::KEY_ELEMS, remainder)?;
223        Ok((T::from_vec(t)?, U::from_vec(u)?, V::from_vec(v.to_vec())?))
224    }
225}
226
227#[cfg(test)]
228mod test {
229    use super::*;
230    use crate::PrimaryKey;
231
232    const BYTES: &[u8] = b"Hello";
233    const STRING: &str = "Hello";
234
235    #[test]
236    #[allow(clippy::unit_cmp)]
237    fn deserialize_empty_works() {
238        assert_eq!(<()>::from_slice(BYTES).unwrap(), ());
239    }
240
241    #[test]
242    fn deserialize_bytes_works() {
243        assert_eq!(<Vec<u8>>::from_slice(BYTES).unwrap(), BYTES);
244        assert_eq!(<&Vec<u8>>::from_slice(BYTES).unwrap(), BYTES);
245        assert_eq!(<&[u8]>::from_slice(BYTES).unwrap(), BYTES);
246        assert_eq!(<[u8; 5]>::from_slice(BYTES).unwrap(), BYTES);
247        assert_eq!(<&[u8; 5]>::from_slice(BYTES).unwrap(), BYTES);
248    }
249
250    #[test]
251    fn deserialize_string_works() {
252        assert_eq!(<String>::from_slice(BYTES).unwrap(), STRING);
253        assert_eq!(<&String>::from_slice(BYTES).unwrap(), STRING);
254        assert_eq!(<&str>::from_slice(BYTES).unwrap(), STRING);
255    }
256
257    #[test]
258    fn deserialize_broken_string_errs() {
259        assert_eq!(
260            "kind: Parsing, error: incomplete utf-8 byte sequence from index 0",
261            <String>::from_slice(b"\xc3").unwrap_err().to_string()
262        );
263    }
264
265    #[test]
266    fn deserialize_addr_works() {
267        assert_eq!(<Addr>::from_slice(BYTES).unwrap(), Addr::unchecked(STRING));
268        assert_eq!(<&Addr>::from_slice(BYTES).unwrap(), Addr::unchecked(STRING));
269    }
270
271    #[test]
272    fn deserialize_broken_addr_errs() {
273        assert_eq!(
274            "kind: Parsing, error: incomplete utf-8 byte sequence from index 0",
275            <Addr>::from_slice(b"\xc3").unwrap_err().to_string()
276        );
277    }
278
279    #[test]
280    fn deserialize_naked_integer_works() {
281        assert_eq!(u8::from_slice(&[1]).unwrap(), 1u8);
282        assert_eq!(i8::from_slice(&[127]).unwrap(), -1i8);
283        assert_eq!(i8::from_slice(&[128]).unwrap(), 0i8);
284
285        assert_eq!(u16::from_slice(&[1, 0]).unwrap(), 256u16);
286        assert_eq!(i16::from_slice(&[128, 0]).unwrap(), 0i16);
287        assert_eq!(i16::from_slice(&[127, 255]).unwrap(), -1i16);
288
289        assert_eq!(u32::from_slice(&[1, 0, 0, 0]).unwrap(), 16777216u32);
290        assert_eq!(i32::from_slice(&[128, 0, 0, 0]).unwrap(), 0i32);
291        assert_eq!(i32::from_slice(&[127, 255, 255, 255]).unwrap(), -1i32);
292
293        assert_eq!(
294            u64::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
295            72057594037927936u64
296        );
297        assert_eq!(i64::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), 0i64);
298        assert_eq!(
299            i64::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(),
300            -1i64
301        );
302
303        assert_eq!(
304            u128::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
305            1329227995784915872903807060280344576u128
306        );
307        assert_eq!(
308            i128::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
309            0i128
310        );
311        assert_eq!(
312            i128::from_slice(&[
313                127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
314            ])
315            .unwrap(),
316            -1i128
317        );
318        assert_eq!(
319            i128::from_slice(&[
320                255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
321            ])
322            .unwrap(),
323            170141183460469231731687303715884105727i128,
324        );
325    }
326
327    #[test]
328    fn deserialize_tuple_works() {
329        assert_eq!(
330            <(&[u8], &str)>::from_slice((BYTES, STRING).joined_key().as_slice()).unwrap(),
331            (BYTES.to_vec(), STRING.to_string())
332        );
333    }
334
335    #[test]
336    fn deserialize_tuple_of_tuples_works() {
337        assert_eq!(
338            <((&[u8], &str), (&[u8], &str))>::from_slice(
339                ((BYTES, STRING), (BYTES, STRING)).joined_key().as_slice()
340            )
341            .unwrap(),
342            (
343                (BYTES.to_vec(), STRING.to_string()),
344                (BYTES.to_vec(), STRING.to_string())
345            )
346        );
347    }
348
349    #[test]
350    fn deserialize_tuple_of_triples_works() {
351        assert_eq!(
352            <((&[u8], &str, u32), (&[u8], &str, u16))>::from_slice(
353                ((BYTES, STRING, 1234u32), (BYTES, STRING, 567u16))
354                    .joined_key()
355                    .as_slice()
356            )
357            .unwrap(),
358            (
359                (BYTES.to_vec(), STRING.to_string(), 1234),
360                (BYTES.to_vec(), STRING.to_string(), 567)
361            )
362        );
363    }
364
365    #[test]
366    fn deserialize_triple_of_tuples_works() {
367        assert_eq!(
368            <((u32, &str), (&str, &[u8]), (i32, i32))>::from_slice(
369                ((1234u32, STRING), (STRING, BYTES), (1234i32, 567i32))
370                    .joined_key()
371                    .as_slice()
372            )
373            .unwrap(),
374            (
375                (1234, STRING.to_string()),
376                (STRING.to_string(), BYTES.to_vec()),
377                (1234, 567)
378            )
379        );
380    }
381
382    #[test]
383    fn deserialize_triple_of_triples_works() {
384        assert_eq!(
385            <((u32, &str, &str), (&str, &[u8], u8), (i32, u8, i32))>::from_slice(
386                (
387                    (1234u32, STRING, STRING),
388                    (STRING, BYTES, 123u8),
389                    (4567i32, 89u8, 10i32)
390                )
391                    .joined_key()
392                    .as_slice()
393            )
394            .unwrap(),
395            (
396                (1234, STRING.to_string(), STRING.to_string()),
397                (STRING.to_string(), BYTES.to_vec(), 123),
398                (4567, 89, 10)
399            )
400        );
401    }
402
403    #[test]
404    fn deserialize_triple_works() {
405        assert_eq!(
406            <(&[u8], u32, &str)>::from_slice((BYTES, 1234u32, STRING).joined_key().as_slice())
407                .unwrap(),
408            (BYTES.to_vec(), 1234, STRING.to_string())
409        );
410    }
411}