From 51a0bdfc1668eb96d2a30328ee82643d1af56a57 Mon Sep 17 00:00:00 2001 From: Ivan Kalinin Date: Thu, 14 Sep 2023 13:59:46 +0200 Subject: [PATCH] Add event builder --- src/abi/contract.rs | 85 +++++++++++++++++++++++++++++++++++++++++++-- src/abi/mod.rs | 4 ++- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/abi/contract.rs b/src/abi/contract.rs index 2ffb2212..0a19db63 100644 --- a/src/abi/contract.rs +++ b/src/abi/contract.rs @@ -553,8 +553,12 @@ impl FunctionBuilder { } /// Sets method input types to the specified list of named arguments. - pub fn with_inputs>(mut self, inputs: I) -> Self { - self.inputs = inputs.into_iter().collect(); + pub fn with_inputs(mut self, inputs: I) -> Self + where + I: IntoIterator, + T: Into, + { + self.inputs = inputs.into_iter().map(Into::into).collect(); self } @@ -569,7 +573,11 @@ impl FunctionBuilder { } /// Sets method output types to the specified list of named arguments. - pub fn with_outputs>(mut self, outputs: I) -> Self { + pub fn with_outputs(mut self, outputs: I) -> Self + where + I: IntoIterator, + T: Into, + { self.outputs = outputs.into_iter().collect(); self } @@ -619,6 +627,12 @@ impl Event { u32::from_be_bytes(hash[0..4].try_into().unwrap()) } + /// Returns an event builder with the specified ABI version and name. + #[inline] + pub fn builder>(abi_version: AbiVersion, name: T) -> EventBuilder { + EventBuilder::new(abi_version, name) + } + /// Encodes a message body with this event as an internal message. pub fn encode_internal_input(&self, tokens: &[NamedAbiValue]) -> Result { ok!(NamedAbiValue::check_types(tokens, &self.inputs)); @@ -667,6 +681,71 @@ impl Event { } } +/// Event ABI declaration builder. +#[derive(Debug, Clone)] +pub struct EventBuilder { + abi_version: AbiVersion, + name: String, + inputs: Vec, + id: Option, +} + +impl EventBuilder { + /// Creates an empty ABI declaration for an event with the specified ABI version and name. + pub fn new>(abi_version: AbiVersion, name: T) -> Self { + Self { + abi_version, + name: name.into(), + inputs: Default::default(), + id: None, + } + } + + /// Finalizes an ABI declaration. + pub fn build(self) -> Event { + let id = match self.id { + Some(id) => id, + None => { + let id = Event::compute_event_id(self.abi_version, &self.name, &self.inputs); + id & Function::INPUT_ID_MASK + } + }; + + Event { + abi_version: self.abi_version, + name: Arc::from(self.name), + inputs: Arc::from(self.inputs), + id, + } + } + + /// Sets event input types to the specified list of named arguments. + pub fn with_inputs(mut self, inputs: I) -> Self + where + I: IntoIterator, + T: Into, + { + self.inputs = inputs.into_iter().map(Into::into).collect(); + self + } + + /// Sets event input types to the specified list of unnamed arguments. + pub fn with_unnamed_inputs>(mut self, inputs: I) -> Self { + self.inputs = inputs + .into_iter() + .enumerate() + .map(NamedAbiType::from) + .collect(); + self + } + + /// Sets an explicit event id. + pub fn with_id(mut self, id: u32) -> Self { + self.id = Some(id); + self + } +} + /// Unsigned external message. pub struct UnsignedExternalMessage { /// Destination contract address. diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 79a550c5..3999ace9 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -2,7 +2,9 @@ use std::str::FromStr; -pub use self::contract::{Contract, Function, UnsignedBody, UnsignedExternalMessage}; +pub use self::contract::{ + Contract, Event, EventBuilder, Function, FunctionBuilder, UnsignedBody, UnsignedExternalMessage, +}; pub use self::signature::{extend_signature_with_id, sign_with_signature_id}; pub use self::traits::{IntoAbi, IntoPlainAbi, WithAbiType, WithPlainAbiType}; pub use self::ty::{