use alloy::primitives::{Address, map::HashSet};
use core::future::{self, Future};
use std::sync::{Arc, Mutex};
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AliasError {
#[error(transparent)]
Internal(Box<dyn core::error::Error + Send + Sync>),
}
pub trait AliasOracle {
fn should_alias(
&self,
address: Address,
) -> impl Future<Output = Result<bool, AliasError>> + Send;
}
impl AliasOracle for HashSet<Address> {
fn should_alias(
&self,
address: Address,
) -> impl Future<Output = Result<bool, AliasError>> + Send {
future::ready(Ok(self.contains(&address)))
}
}
pub trait AliasOracleFactory: Send + Sync + 'static {
type Oracle: AliasOracle;
fn create(&self) -> Result<Self::Oracle, AliasError>;
}
impl AliasOracleFactory for HashSet<Address> {
type Oracle = HashSet<Address>;
fn create(&self) -> Result<Self::Oracle, AliasError> {
Ok(self.clone())
}
}
impl<T> AliasOracleFactory for Mutex<T>
where
T: AliasOracleFactory,
{
type Oracle = T::Oracle;
fn create(&self) -> Result<Self::Oracle, AliasError> {
let guard = self.lock().map_err(|e| AliasError::Internal(e.to_string().into()))?;
guard.create()
}
}
impl<T> AliasOracleFactory for Arc<T>
where
T: AliasOracleFactory,
{
type Oracle = T::Oracle;
fn create(&self) -> Result<Self::Oracle, AliasError> {
self.as_ref().create()
}
}