avail_rust_core/
decoded_events.rs1use codec::{Decode, Encode};
2use serde::{Deserialize, Serialize};
3
4pub trait HasEventEmittedIndex {
5 const EMITTED_INDEX: (u8, u8);
7}
8
9pub trait TransactionEventEncodable {
10 fn encode_as_event(&self) -> Vec<u8>;
14
15 fn encode_as_hex_event(&self) -> String;
19}
20
21pub trait TransactionEventDecodable {
22 fn decode_event(event: &[u8]) -> Option<Box<Self>>;
26
27 fn decode_hex_event(event: &str) -> Option<Box<Self>>;
32
33 fn decode_event_data(event_data: &[u8]) -> Option<Box<Self>>;
35}
36
37impl<T: HasEventEmittedIndex + Encode> TransactionEventEncodable for T {
38 fn encode_as_event(&self) -> Vec<u8> {
39 let pallet_id = Self::EMITTED_INDEX.0;
40 let variant_id = Self::EMITTED_INDEX.1;
41 let mut encoded_event: Vec<u8> = vec![pallet_id, variant_id];
42 Self::encode_to(self, &mut encoded_event);
43
44 encoded_event
45 }
46
47 fn encode_as_hex_event(&self) -> String {
48 std::format!("0x{}", const_hex::encode(Self::encode_as_event(self)))
49 }
50}
51
52impl<T: HasEventEmittedIndex + Decode> TransactionEventDecodable for T {
53 fn decode_event(event: &[u8]) -> Option<Box<T>> {
54 if !event_filter_in(event, Self::EMITTED_INDEX) {
56 return None;
57 }
58
59 if event.len() <= 2 {
60 try_decode_event_data(&[])
61 } else {
62 try_decode_event_data(&event[2..])
63 }
64 }
65
66 #[inline(always)]
67 fn decode_hex_event(event: &str) -> Option<Box<T>> {
68 let hex_decoded = const_hex::decode(event.trim_start_matches("0x")).ok()?;
69 Self::decode_event(&hex_decoded)
70 }
71
72 fn decode_event_data(event_data: &[u8]) -> Option<Box<T>> {
73 try_decode_event_data(event_data)
75 }
76}
77
78#[inline(never)]
80fn try_decode_event_data<T: Decode>(mut event_data: &[u8]) -> Option<Box<T>> {
81 T::decode(&mut event_data).ok().map(Box::new)
82}
83
84#[inline(never)]
86fn event_filter_in(event: &[u8], emitted_index: (u8, u8)) -> bool {
87 if event.len() < 2 {
88 return false;
89 }
90
91 let (pallet_id, variant_id) = (event[0], event[1]);
92 if emitted_index.0 != pallet_id || emitted_index.1 != variant_id {
93 return false;
94 }
95
96 true
97}
98
99#[derive(Debug, Clone)]
101pub struct OpaqueEvent(pub Vec<u8>);
102
103impl OpaqueEvent {
104 pub fn pallet_index(&self) -> u8 {
105 self.0[0]
106 }
107
108 pub fn variant_index(&self) -> u8 {
109 self.0[1]
110 }
111
112 pub fn event_data(&self) -> &[u8] {
113 if self.0.len() <= 2 { &[] } else { &self.0[2..] }
114 }
115}
116
117impl TryFrom<String> for OpaqueEvent {
118 type Error = String;
119
120 fn try_from(value: String) -> Result<Self, Self::Error> {
121 Self::try_from(value.as_str())
122 }
123}
124
125impl TryFrom<&String> for OpaqueEvent {
126 type Error = String;
127
128 fn try_from(value: &String) -> Result<Self, Self::Error> {
129 Self::try_from(value.as_str())
130 }
131}
132
133impl TryFrom<&str> for OpaqueEvent {
134 type Error = String;
135
136 fn try_from(value: &str) -> Result<Self, Self::Error> {
137 let value = const_hex::decode(value).map_err(|x| x.to_string())?;
138 Self::try_from(value)
139 }
140}
141
142impl TryFrom<Vec<u8>> for OpaqueEvent {
143 type Error = String;
144
145 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
146 Self::try_from(value.as_slice())
147 }
148}
149
150impl TryFrom<&Vec<u8>> for OpaqueEvent {
151 type Error = String;
152
153 fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
154 Self::try_from(value.as_slice())
155 }
156}
157
158impl TryFrom<&[u8]> for OpaqueEvent {
159 type Error = String;
160
161 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
162 if value.len() < 2 {
163 return Err("Event must have more than one byte".into());
164 }
165
166 Ok(OpaqueEvent(value.to_owned()))
167 }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
172pub enum RuntimePhase {
173 ApplyExtrinsic(u32),
175 Finalization,
177 Initialization,
179}