use alloy_primitives::BlockNumber;
use auto_impl::auto_impl;
use core::fmt::Debug;
mod factory;
mod gas;
mod oracle;
mod salt;
#[cfg(any(test, feature = "test-utils"))]
mod test_utils;
pub use factory::*;
pub use gas::*;
pub use oracle::*;
pub use salt::*;
#[cfg(any(test, feature = "test-utils"))]
pub use test_utils::*;
#[auto_impl(&, Box, Arc)]
pub trait ExternalEnvTypes {
type SaltEnv: SaltEnv;
type OracleEnv: OracleEnv;
}
impl<A: SaltEnv, B: OracleEnv> ExternalEnvTypes for (A, B) {
type SaltEnv = A;
type OracleEnv = B;
}
#[derive(Debug, Clone)]
pub struct ExternalEnvs<T: ExternalEnvTypes> {
pub salt_env: T::SaltEnv,
pub oracle_env: T::OracleEnv,
}
impl Default for ExternalEnvs<EmptyExternalEnv> {
fn default() -> Self {
Self { salt_env: EmptyExternalEnv, oracle_env: EmptyExternalEnv }
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct EmptyExternalEnv;
impl ExternalEnvTypes for EmptyExternalEnv {
type SaltEnv = Self;
type OracleEnv = Self;
}
impl ExternalEnvFactory for EmptyExternalEnv {
type EnvTypes = Self;
fn external_envs(&self, _block: BlockNumber) -> ExternalEnvs<Self::EnvTypes> {
ExternalEnvs { salt_env: *self, oracle_env: *self }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{OracleEnv, SaltEnv, MIN_BUCKET_SIZE};
use alloy_primitives::{Address, Bytes, B256, U256};
#[test]
fn test_empty_external_env_factory_returns_minimum_bucket_and_no_oracle() {
let envs = EmptyExternalEnv.external_envs(42);
assert_eq!(envs.salt_env.get_bucket_capacity(123).unwrap(), MIN_BUCKET_SIZE as u64);
assert_eq!(envs.oracle_env.get_oracle_storage(U256::from(7)), None);
envs.oracle_env.on_hint(Address::ZERO, B256::ZERO, Bytes::new());
assert_eq!(<EmptyExternalEnv as SaltEnv>::bucket_id_for_account(Address::ZERO), 0);
assert_eq!(<EmptyExternalEnv as SaltEnv>::bucket_id_for_slot(Address::ZERO, U256::ZERO), 0);
}
}