use alloy_primitives::{Address, Bytes, U256};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Interaction {
pub target: Address,
pub value: U256,
pub call_data: Bytes,
}
#[derive(Debug, Clone)]
pub struct InteractionLike {
pub target: Address,
pub value: Option<U256>,
pub call_data: Option<Bytes>,
}
impl InteractionLike {
#[must_use]
pub const fn new(target: Address) -> Self {
Self { target, value: None, call_data: None }
}
#[must_use]
pub const fn with_value(mut self, value: U256) -> Self {
self.value = Some(value);
self
}
#[must_use]
pub fn with_call_data(mut self, call_data: Bytes) -> Self {
self.call_data = Some(call_data);
self
}
}
#[must_use]
pub fn normalize_interaction(interaction: InteractionLike) -> Interaction {
Interaction {
target: interaction.target,
value: interaction.value.map_or(U256::ZERO, |v| v),
call_data: interaction.call_data.unwrap_or_default(),
}
}
#[must_use]
pub fn normalize_interactions(interactions: Vec<InteractionLike>) -> Vec<Interaction> {
interactions.into_iter().map(normalize_interaction).collect()
}
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::bytes;
#[test]
fn normalize_defaults() {
let like = InteractionLike::new(Address::ZERO);
let norm = normalize_interaction(like);
assert_eq!(norm.target, Address::ZERO);
assert_eq!(norm.value, U256::ZERO);
assert!(norm.call_data.is_empty());
}
#[test]
fn normalize_with_values() {
let data = bytes!("deadbeef");
let like = InteractionLike::new(Address::ZERO)
.with_value(U256::from(42))
.with_call_data(data.clone());
let norm = normalize_interaction(like);
assert_eq!(norm.value, U256::from(42));
assert_eq!(norm.call_data, data);
}
#[test]
fn normalize_multiple() {
let interactions = vec![
InteractionLike::new(Address::ZERO),
InteractionLike::new(Address::ZERO).with_value(U256::from(1)),
];
let normalized = normalize_interactions(interactions);
assert_eq!(normalized.len(), 2);
assert_eq!(normalized[0].value, U256::ZERO);
assert_eq!(normalized[1].value, U256::from(1));
}
}