axiom_codec/decoder/
field_elements.rs

1use std::io::{Error, ErrorKind, Result};
2
3use crate::{
4    constants::MAX_SOLIDITY_MAPPING_KEYS,
5    encoder::field_elements::{
6        NUM_FE_SOLIDITY_NESTED_MAPPING, NUM_FE_SOLIDITY_NESTED_MAPPING_WITHOUT_KEYS,
7    },
8    types::field_elements::{
9        FieldAccountSubquery, FieldHeaderSubquery, FieldReceiptSubquery,
10        FieldSolidityNestedMappingSubquery, FieldStorageSubquery, FieldTxSubquery,
11        FlattenedSubqueryResult, SubqueryKey, SubqueryOutput, SUBQUERY_KEY_LEN,
12        SUBQUERY_RESULT_LEN,
13    },
14    HiLo,
15};
16
17impl<T> TryFrom<Vec<T>> for FlattenedSubqueryResult<T> {
18    type Error = Error;
19
20    fn try_from(value: Vec<T>) -> Result<Self> {
21        if value.len() != SUBQUERY_RESULT_LEN {
22            return Err(Error::new(ErrorKind::InvalidInput, "invalid array length"));
23        }
24        let mut key = value;
25        let value = key.split_off(SUBQUERY_KEY_LEN);
26        let key = key.try_into().map_err(|_| Error::other("should never happen"))?;
27        let value = value.try_into().map_err(|_| Error::other("should never happen"))?;
28        Ok(Self { key: SubqueryKey(key), value: SubqueryOutput(value) })
29    }
30}
31
32impl<T> TryFrom<Vec<T>> for FieldHeaderSubquery<T> {
33    type Error = Error;
34
35    fn try_from(value: Vec<T>) -> Result<Self> {
36        let [block_number, field_idx] = value
37            .try_into()
38            .map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid array length"))?;
39        Ok(Self { block_number, field_idx })
40    }
41}
42
43impl<T> TryFrom<Vec<T>> for FieldAccountSubquery<T> {
44    type Error = Error;
45
46    fn try_from(value: Vec<T>) -> Result<Self> {
47        let [block_number, addr, field_idx] = value
48            .try_into()
49            .map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid array length"))?;
50        Ok(Self { block_number, addr, field_idx })
51    }
52}
53
54impl<T> TryFrom<Vec<T>> for FieldStorageSubquery<T> {
55    type Error = Error;
56
57    fn try_from(value: Vec<T>) -> Result<Self> {
58        let [block_number, addr, slot_hi, slot_lo] = value
59            .try_into()
60            .map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid array length"))?;
61        Ok(Self { block_number, addr, slot: HiLo::from_hi_lo([slot_hi, slot_lo]) })
62    }
63}
64
65impl<T> TryFrom<Vec<T>> for FieldTxSubquery<T> {
66    type Error = Error;
67
68    fn try_from(value: Vec<T>) -> Result<Self> {
69        let [block_number, tx_idx, field_or_calldata_idx] = value
70            .try_into()
71            .map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid array length"))?;
72        Ok(Self { block_number, tx_idx, field_or_calldata_idx })
73    }
74}
75
76impl<T> TryFrom<Vec<T>> for FieldReceiptSubquery<T> {
77    type Error = Error;
78
79    fn try_from(value: Vec<T>) -> Result<Self> {
80        let [block_number, tx_idx, field_or_log_idx, topic_or_data_or_address_idx, event_schema_hi, event_schema_lo] =
81            value
82                .try_into()
83                .map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid array length"))?;
84        Ok(Self {
85            block_number,
86            tx_idx,
87            field_or_log_idx,
88            topic_or_data_or_address_idx,
89            event_schema: HiLo::from_hi_lo([event_schema_hi, event_schema_lo]),
90        })
91    }
92}
93
94impl<T> TryFrom<Vec<T>> for FieldSolidityNestedMappingSubquery<T> {
95    type Error = Error;
96
97    fn try_from(mut value: Vec<T>) -> Result<Self> {
98        if value.len() != NUM_FE_SOLIDITY_NESTED_MAPPING {
99            return Err(Error::new(ErrorKind::InvalidInput, "invalid array length"));
100        }
101        let keys = value.split_off(NUM_FE_SOLIDITY_NESTED_MAPPING_WITHOUT_KEYS);
102        let [block_number, addr, slot_hi, slot_lo, mapping_depth] =
103            value.try_into().map_err(|_| Error::other("should never happen"))?;
104        let mut keys_iter = keys.into_iter();
105        let keys: Vec<_> = (0..MAX_SOLIDITY_MAPPING_KEYS)
106            .map(|_| {
107                let key_hi = keys_iter.next().unwrap();
108                let key_lo = keys_iter.next().unwrap();
109                HiLo::from_hi_lo([key_hi, key_lo])
110            })
111            .collect();
112        Ok(Self {
113            block_number,
114            addr,
115            mapping_slot: HiLo::from_hi_lo([slot_hi, slot_lo]),
116            mapping_depth,
117            keys: keys.try_into().map_err(|_| Error::other("max keys wrong length"))?,
118        })
119    }
120}