use alloc::vec::Vec;
use miden_protocol::account::{AccountComponent, AccountProcedureRoot};
use thiserror::Error;
mod basic_constant_fee;
mod constant_fee_manager;
pub use basic_constant_fee::BasicConstantFeePolicy;
pub use constant_fee_manager::ConstantFeeManager;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
pub enum FeePolicyError {
#[error("custom fee policy root must match a procedure root in one of the provided components")]
RootNotInComponents,
}
#[derive(Debug, Clone)]
pub struct FeePolicy {
root: AccountProcedureRoot,
components: Vec<AccountComponent>,
}
impl FeePolicy {
pub fn custom<I>(root: AccountProcedureRoot, components: I) -> Result<Self, FeePolicyError>
where
I: IntoIterator,
I::Item: Into<AccountComponent>,
{
let components: Vec<AccountComponent> = components.into_iter().map(Into::into).collect();
if !components.iter().any(|component| component.has_procedure(root)) {
return Err(FeePolicyError::RootNotInComponents);
}
Ok(Self { root, components })
}
pub fn root(&self) -> AccountProcedureRoot {
self.root
}
}
impl From<BasicConstantFeePolicy> for FeePolicy {
fn from(policy: BasicConstantFeePolicy) -> Self {
Self {
root: BasicConstantFeePolicy::root(),
components: vec![policy.into()],
}
}
}
impl IntoIterator for FeePolicy {
type Item = AccountComponent;
type IntoIter = alloc::vec::IntoIter<AccountComponent>;
fn into_iter(self) -> Self::IntoIter {
self.components.into_iter()
}
}