use compact_str::CompactString;
use r402_protocol::ChainIdPattern;
use crate::candidate::PaymentCandidate;
pub trait PaymentPolicy: Send + Sync {
fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate>;
}
#[derive(Debug, Default)]
pub struct NetworkPolicy(Vec<ChainIdPattern>);
impl NetworkPolicy {
#[must_use]
pub fn new<P: Into<Vec<ChainIdPattern>>>(patterns: P) -> Self {
Self(patterns.into())
}
}
impl PaymentPolicy for NetworkPolicy {
fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
candidates
.into_iter()
.filter(|c| self.0.iter().any(|p| p.matches(&c.chain_id)))
.collect()
}
}
#[derive(Debug, Default)]
pub struct SchemePolicy(Vec<CompactString>);
impl SchemePolicy {
#[must_use]
pub fn new<S: Into<CompactString>, I: IntoIterator<Item = S>>(schemes: I) -> Self {
Self(schemes.into_iter().map(Into::into).collect())
}
}
impl PaymentPolicy for SchemePolicy {
fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
candidates
.into_iter()
.filter(|c| self.0.iter().any(|s| s.as_str() == c.scheme.as_str()))
.collect()
}
}
#[derive(Debug, Clone, Copy)]
pub struct MaxAmountPolicy(pub u128);
impl PaymentPolicy for MaxAmountPolicy {
fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
candidates
.into_iter()
.filter(|c| c.amount.parse::<u128>().is_ok_and(|a| a <= self.0))
.collect()
}
}