mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 17:01:09 +00:00
Wrap the subxt::events::Events type to avoid exposing subxt_core errors and types unnecessarily (#1948)
* Wrap the subxt::events::Events type to avoid exposing subxt_core errors and types unnecessarily (#1947) * Actually import module and fix issues * Remove a couple of unnecessary conversions now * Test
This commit is contained in:
+2
-2
@@ -75,7 +75,7 @@ pub trait StaticEvent: DecodeAsFields {
|
||||
/// A collection of events obtained from a block, bundled with the necessary
|
||||
/// information needed to decode and iterate over them.
|
||||
#[derive_where(Clone)]
|
||||
pub struct Events<T: Config> {
|
||||
pub struct Events<T> {
|
||||
metadata: Metadata,
|
||||
// Note; raw event bytes are prefixed with a Compact<u32> containing
|
||||
// the number of events to be decoded. The start_idx reflects that, so
|
||||
@@ -87,7 +87,7 @@ pub struct Events<T: Config> {
|
||||
}
|
||||
|
||||
// Ignore the Metadata when debug-logging events; it's big and distracting.
|
||||
impl<T: Config> core::fmt::Debug for Events<T> {
|
||||
impl<T> core::fmt::Debug for Events<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Events")
|
||||
.field("event_bytes", &self.event_bytes)
|
||||
|
||||
@@ -308,14 +308,11 @@ impl<T: Config> ExtrinsicEvents<T> {
|
||||
/// This works in the same way that [`events::Events::iter()`] does, with the
|
||||
/// exception that it filters out events not related to the submitted extrinsic.
|
||||
pub fn iter(&self) -> impl Iterator<Item = Result<events::EventDetails<T>, Error>> + '_ {
|
||||
self.events
|
||||
.iter()
|
||||
.filter(|ev| {
|
||||
ev.as_ref()
|
||||
.map(|ev| ev.phase() == events::Phase::ApplyExtrinsic(self.idx))
|
||||
.unwrap_or(true) // Keep any errors.
|
||||
})
|
||||
.map(|e| e.map_err(Error::from))
|
||||
self.events.iter().filter(|ev| {
|
||||
ev.as_ref()
|
||||
.map(|ev| ev.phase() == events::Phase::ApplyExtrinsic(self.idx))
|
||||
.unwrap_or(true) // Keep any errors.
|
||||
})
|
||||
}
|
||||
|
||||
/// Find all of the transaction events matching the event type provided as a generic parameter.
|
||||
@@ -323,10 +320,8 @@ impl<T: Config> ExtrinsicEvents<T> {
|
||||
/// This works in the same way that [`events::Events::find()`] does, with the
|
||||
/// exception that it filters out events not related to the submitted extrinsic.
|
||||
pub fn find<Ev: events::StaticEvent>(&self) -> impl Iterator<Item = Result<Ev, Error>> + '_ {
|
||||
self.iter().filter_map(|ev| {
|
||||
ev.and_then(|ev| ev.as_event::<Ev>().map_err(Into::into))
|
||||
.transpose()
|
||||
})
|
||||
self.iter()
|
||||
.filter_map(|ev| ev.and_then(|ev| ev.as_event::<Ev>()).transpose())
|
||||
}
|
||||
|
||||
/// Iterate through the transaction events using metadata to dynamically decode and skip
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
use crate::{Config, Error, Metadata};
|
||||
use derive_where::derive_where;
|
||||
use scale_decode::DecodeAsType;
|
||||
use subxt_core::events::{EventDetails as CoreEventDetails, Events as CoreEvents};
|
||||
|
||||
pub use subxt_core::events::{EventMetadataDetails, Phase, StaticEvent};
|
||||
|
||||
/// A collection of events obtained from a block, bundled with the necessary
|
||||
/// information needed to decode and iterate over them.
|
||||
// Dev note: we are just wrapping the subxt_core types here to avoid leaking them
|
||||
// in Subxt and map any errors into Subxt errors so that we don't have this part of the
|
||||
// API returning a different error type (ie the subxt_core::Error).
|
||||
#[derive_where(Clone, Debug)]
|
||||
pub struct Events<T> {
|
||||
inner: CoreEvents<T>,
|
||||
}
|
||||
|
||||
impl<T: Config> Events<T> {
|
||||
/// Create a new [`Events`] instance from the given bytes.
|
||||
pub fn decode_from(event_bytes: Vec<u8>, metadata: Metadata) -> Self {
|
||||
Self {
|
||||
inner: CoreEvents::decode_from(event_bytes, metadata),
|
||||
}
|
||||
}
|
||||
|
||||
/// The number of events.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.inner.len()
|
||||
}
|
||||
|
||||
/// Are there no events in this block?
|
||||
// Note: mainly here to satisfy clippy..
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
/// Return the bytes representing all of the events.
|
||||
pub fn bytes(&self) -> &[u8] {
|
||||
self.inner.bytes()
|
||||
}
|
||||
|
||||
/// Iterate over all of the events, using metadata to dynamically
|
||||
/// decode them as we go, and returning the raw bytes and other associated
|
||||
/// details. If an error occurs, all subsequent iterations return `None`.
|
||||
// Dev note: The returned iterator is 'static + Send so that we can box it up and make
|
||||
// use of it with our `FilterEvents` stuff.
|
||||
pub fn iter(
|
||||
&self,
|
||||
) -> impl Iterator<Item = Result<EventDetails<T>, Error>> + Send + Sync + 'static {
|
||||
self.inner
|
||||
.iter()
|
||||
.map(|item| item.map(|e| EventDetails { inner: e }).map_err(Into::into))
|
||||
}
|
||||
|
||||
/// Iterate through the events using metadata to dynamically decode and skip
|
||||
/// them, and return only those which should decode to the provided `Ev` type.
|
||||
/// If an error occurs, all subsequent iterations return `None`.
|
||||
pub fn find<Ev: StaticEvent>(&self) -> impl Iterator<Item = Result<Ev, Error>> + '_ {
|
||||
self.inner.find::<Ev>().map(|item| item.map_err(Into::into))
|
||||
}
|
||||
|
||||
/// Iterate through the events using metadata to dynamically decode and skip
|
||||
/// them, and return the first event found which decodes to the provided `Ev` type.
|
||||
pub fn find_first<Ev: StaticEvent>(&self) -> Result<Option<Ev>, Error> {
|
||||
self.inner.find_first::<Ev>().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Iterate through the events using metadata to dynamically decode and skip
|
||||
/// them, and return the last event found which decodes to the provided `Ev` type.
|
||||
pub fn find_last<Ev: StaticEvent>(&self) -> Result<Option<Ev>, Error> {
|
||||
self.inner.find_last::<Ev>().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Find an event that decodes to the type provided. Returns true if it was found.
|
||||
pub fn has<Ev: StaticEvent>(&self) -> Result<bool, Error> {
|
||||
self.inner.has::<Ev>().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
/// The event details.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EventDetails<T: Config> {
|
||||
inner: CoreEventDetails<T>,
|
||||
}
|
||||
|
||||
impl<T: Config> EventDetails<T> {
|
||||
/// When was the event produced?
|
||||
pub fn phase(&self) -> Phase {
|
||||
self.inner.phase()
|
||||
}
|
||||
|
||||
/// What index is this event in the stored events for this block.
|
||||
pub fn index(&self) -> u32 {
|
||||
self.inner.index()
|
||||
}
|
||||
|
||||
/// The index of the pallet that the event originated from.
|
||||
pub fn pallet_index(&self) -> u8 {
|
||||
self.inner.pallet_index()
|
||||
}
|
||||
|
||||
/// The index of the event variant that the event originated from.
|
||||
pub fn variant_index(&self) -> u8 {
|
||||
self.inner.variant_index()
|
||||
}
|
||||
|
||||
/// The name of the pallet from whence the Event originated.
|
||||
pub fn pallet_name(&self) -> &str {
|
||||
self.inner.pallet_name()
|
||||
}
|
||||
|
||||
/// The name of the event (ie the name of the variant that it corresponds to).
|
||||
pub fn variant_name(&self) -> &str {
|
||||
self.inner.variant_name()
|
||||
}
|
||||
|
||||
/// Fetch details from the metadata for this event.
|
||||
pub fn event_metadata(&self) -> EventMetadataDetails {
|
||||
self.inner.event_metadata()
|
||||
}
|
||||
|
||||
/// Return _all_ of the bytes representing this event, which include, in order:
|
||||
/// - The phase.
|
||||
/// - Pallet and event index.
|
||||
/// - Event fields.
|
||||
/// - Event Topics.
|
||||
pub fn bytes(&self) -> &[u8] {
|
||||
self.inner.bytes()
|
||||
}
|
||||
|
||||
/// Return the bytes representing the fields stored in this event.
|
||||
pub fn field_bytes(&self) -> &[u8] {
|
||||
self.inner.field_bytes()
|
||||
}
|
||||
|
||||
/// Decode and provide the event fields back in the form of a [`scale_value::Composite`]
|
||||
/// type which represents the named or unnamed fields that were present in the event.
|
||||
pub fn field_values(&self) -> Result<scale_value::Composite<u32>, Error> {
|
||||
self.inner.field_values().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Attempt to decode these [`EventDetails`] into a type representing the event fields.
|
||||
/// Such types are exposed in the codegen as `pallet_name::events::EventName` types.
|
||||
pub fn as_event<E: StaticEvent>(&self) -> Result<Option<E>, Error> {
|
||||
self.inner.as_event::<E>().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Attempt to decode these [`EventDetails`] into a root event type (which includes
|
||||
/// the pallet and event enum variants as well as the event fields). A compatible
|
||||
/// type for this is exposed via static codegen as a root level `Event` type.
|
||||
pub fn as_root_event<E: DecodeAsType>(&self) -> Result<E, Error> {
|
||||
self.inner.as_root_event::<E>().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Return the topics associated with this event.
|
||||
pub fn topics(&self) -> &[T::Hash] {
|
||||
self.inner.topics()
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,16 @@
|
||||
//! This module exposes the types and such necessary for working with events.
|
||||
//! The two main entry points into events are [`crate::OnlineClient::events()`]
|
||||
//! and calls like [crate::tx::TxProgress::wait_for_finalized_success()].
|
||||
|
||||
mod events_client;
|
||||
mod events_type;
|
||||
|
||||
use crate::client::OnlineClientT;
|
||||
use crate::Error;
|
||||
use subxt_core::{Config, Metadata};
|
||||
|
||||
mod events_client;
|
||||
pub use events_client::EventsClient;
|
||||
pub use subxt_core::events::{EventDetails, Events, Phase, StaticEvent};
|
||||
pub use events_type::{EventDetails, EventMetadataDetails, Events, Phase, StaticEvent};
|
||||
|
||||
/// Creates a new [`Events`] instance by fetching the corresponding bytes at `block_hash` from the client.
|
||||
pub async fn new_events_from_client<T, C>(
|
||||
|
||||
Reference in New Issue
Block a user