avail_rust_core/
decoded_events.rs1use crate::{HasHeader, types::metadata::StringOrBytes};
2use codec::{Decode, Encode};
3
4pub trait TransactionEventEncodable {
5 fn to_event(&self) -> Vec<u8>;
9}
10
11pub trait TransactionEventDecodable: Sized {
12 fn from_event<'a>(event: impl Into<StringOrBytes<'a>>) -> Result<Self, String>;
16}
17
18impl<T: HasHeader + Encode> TransactionEventEncodable for T {
19 fn to_event(&self) -> Vec<u8> {
20 let pallet_id = Self::HEADER_INDEX.0;
21 let variant_id = Self::HEADER_INDEX.1;
22 let mut encoded_event: Vec<u8> = vec![pallet_id, variant_id];
23 Self::encode_to(self, &mut encoded_event);
24
25 encoded_event
26 }
27}
28
29impl<T: HasHeader + Decode> TransactionEventDecodable for T {
30 fn from_event<'a>(event: impl Into<StringOrBytes<'a>>) -> Result<Self, String> {
31 fn inner<T: HasHeader + Decode>(event: StringOrBytes) -> Result<T, String> {
32 let event: &[u8] = match &event {
33 StringOrBytes::StringRef(s) => {
34 &const_hex::decode(s.trim_start_matches("0x")).map_err(|x| x.to_string())?
35 },
36 StringOrBytes::BoxedString(s) => {
37 &const_hex::decode(s.trim_start_matches("0x")).map_err(|x| x.to_string())?
38 },
39 StringOrBytes::Bytes(b) => b,
40 StringOrBytes::BoxedBytes(b) => b,
41 };
42
43 check_header(event, T::HEADER_INDEX)?;
45
46 if event.len() <= 2 {
47 let mut data: &[u8] = &[];
48 Ok(T::decode(&mut data).map_err(|x| x.to_string())?)
49 } else {
50 let mut data = &event[2..];
51 Ok(T::decode(&mut data).map_err(|x| x.to_string())?)
52 }
53 }
54
55 inner(event.into())
56 }
57}
58
59pub(crate) fn check_header(data: &[u8], header_index: (u8, u8)) -> Result<(), String> {
61 if data.len() < 2 {
62 return Err("Failed to decode. Not have enough bytes to decode the header".into());
63 }
64
65 let (pallet_id, variant_id) = (data[0], data[1]);
66 if header_index.0 != pallet_id || header_index.1 != variant_id {
67 let err = std::format!(
68 "Failed to decode. Mismatch in pallet and/or variant id. Actual: PI: {}, VI: {} Expected: PI: {}, VI: {}",
69 pallet_id,
70 variant_id,
71 header_index.0,
72 header_index.1
73 );
74 return Err(err);
75 }
76
77 Ok(())
78}
79
80