avail_rust_core/
decoded_events.rs

1use crate::{HasHeader, types::metadata::StringOrBytes};
2use codec::{Decode, Encode};
3
4pub trait TransactionEventEncodable {
5	/// SCALE encodes the event
6	///
7	/// If you need to Hex and SCALE encode then call `encode_as_hex_event`
8	fn to_event(&self) -> Vec<u8>;
9}
10
11pub trait TransactionEventDecodable: Sized {
12	/// Decodes the SCALE encoded Event
13	///
14	/// If you need to decode Hex string call `decode_hex_event`
15	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			// This was moved out in order to decrease compilation times
44			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
59// Purely here to decrease compilation times
60pub(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/* /// Contains only the event body. Phase and topics are not included here.
81#[derive(Debug, Clone)]
82pub struct RawEvent(pub Vec<u8>);
83
84impl RawEvent {
85	pub fn pallet_index(&self) -> u8 {
86		self.0[0]
87	}
88
89	pub fn variant_index(&self) -> u8 {
90		self.0[1]
91	}
92
93	pub fn event_data(&self) -> &[u8] {
94		if self.0.len() <= 2 { &[] } else { &self.0[2..] }
95	}
96}
97
98impl TryFrom<String> for RawEvent {
99	type Error = String;
100
101	fn try_from(value: String) -> Result<Self, Self::Error> {
102		Self::try_from(value.as_str())
103	}
104}
105
106impl TryFrom<&String> for RawEvent {
107	type Error = String;
108
109	fn try_from(value: &String) -> Result<Self, Self::Error> {
110		Self::try_from(value.as_str())
111	}
112}
113
114impl TryFrom<&str> for RawEvent {
115	type Error = String;
116
117	fn try_from(value: &str) -> Result<Self, Self::Error> {
118		let value = const_hex::decode(value).map_err(|x| x.to_string())?;
119		Self::try_from(value)
120	}
121}
122
123impl TryFrom<Vec<u8>> for RawEvent {
124	type Error = String;
125
126	fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
127		Self::try_from(value.as_slice())
128	}
129}
130
131impl TryFrom<&Vec<u8>> for RawEvent {
132	type Error = String;
133
134	fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
135		Self::try_from(value.as_slice())
136	}
137}
138
139impl TryFrom<&[u8]> for RawEvent {
140	type Error = String;
141
142	fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
143		if value.len() < 2 {
144			return Err("Event must have more than one byte".into());
145		}
146
147		Ok(RawEvent(value.to_owned()))
148	}
149}
150 */