use core::fmt::Debug;
#[cfg(doc)]
use crate::{contracttype, Bytes, Map};
use crate::{env::internal, unwrap::UnwrapInfallible, Env, IntoVal, Val, Vec};
const TOPIC_BYTES_LENGTH_LIMIT: u32 = 32;
#[derive(Clone)]
pub struct Events(Env);
impl Debug for Events {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Events")
}
}
pub trait Event {
fn topics(&self, env: &Env) -> Vec<Val>;
fn data(&self, env: &Env) -> Val;
fn publish(&self, env: &Env) {
env.events().publish_event(self);
}
}
pub trait Topics: IntoVal<Env, Vec<Val>> {}
impl<T> Topics for Vec<T> {}
impl Events {
#[inline(always)]
pub(crate) fn env(&self) -> &Env {
&self.0
}
#[inline(always)]
pub(crate) fn new(env: &Env) -> Events {
Events(env.clone())
}
#[inline(always)]
pub fn publish_event(&self, e: &(impl Event + ?Sized)) {
let env = self.env();
internal::Env::contract_event(env, e.topics(env).to_object(), e.data(env))
.unwrap_infallible();
}
#[deprecated(note = "use the #[contractevent] macro on a contract event type")]
#[inline(always)]
pub fn publish<T, D>(&self, topics: T, data: D)
where
T: Topics,
D: IntoVal<Env, Val>,
{
let env = self.env();
internal::Env::contract_event(env, topics.into_val(env).to_object(), data.into_val(env))
.unwrap_infallible();
}
}
#[cfg(any(test, feature = "testutils"))]
use crate::{testutils, xdr, Address, TryIntoVal};
#[cfg(any(test, feature = "testutils"))]
#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
impl testutils::Events for Events {
fn all(&self) -> Vec<(crate::Address, Vec<Val>, Val)> {
let env = self.env();
let mut vec = Vec::new(env);
self.env()
.host()
.get_events()
.unwrap()
.0
.into_iter()
.for_each(|e| {
if e.failed_call {
return;
}
if let xdr::ContractEvent {
type_: xdr::ContractEventType::Contract,
contract_id: Some(contract_id),
body: xdr::ContractEventBody::V0(xdr::ContractEventV0 { topics, data }),
..
} = e.event
{
vec.push_back((
Address::from_contract_id(env, contract_id.0 .0),
topics.try_into_val(env).unwrap(),
data.try_into_val(env).unwrap(),
))
}
});
vec
}
}