1use compact_str::CompactString;
4use r402_protocol::ChainIdPattern;
5
6use crate::candidate::PaymentCandidate;
7
8pub trait PaymentPolicy: Send + Sync {
10 fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate>;
12}
13
14#[derive(Debug, Default)]
16pub struct NetworkPolicy(Vec<ChainIdPattern>);
17
18impl NetworkPolicy {
19 #[must_use]
21 pub fn new<P: Into<Vec<ChainIdPattern>>>(patterns: P) -> Self {
22 Self(patterns.into())
23 }
24}
25
26impl PaymentPolicy for NetworkPolicy {
27 fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
28 candidates
29 .into_iter()
30 .filter(|c| self.0.iter().any(|p| p.matches(&c.chain_id)))
31 .collect()
32 }
33}
34
35#[derive(Debug, Default)]
37pub struct SchemePolicy(Vec<CompactString>);
38
39impl SchemePolicy {
40 #[must_use]
42 pub fn new<S: Into<CompactString>, I: IntoIterator<Item = S>>(schemes: I) -> Self {
43 Self(schemes.into_iter().map(Into::into).collect())
44 }
45}
46
47impl PaymentPolicy for SchemePolicy {
48 fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
49 candidates
50 .into_iter()
51 .filter(|c| self.0.iter().any(|s| s.as_str() == c.scheme.as_str()))
52 .collect()
53 }
54}
55
56#[derive(Debug, Clone, Copy)]
58pub struct MaxAmountPolicy(pub u128);
59
60impl PaymentPolicy for MaxAmountPolicy {
61 fn apply<'a>(&self, candidates: Vec<&'a PaymentCandidate>) -> Vec<&'a PaymentCandidate> {
62 candidates
63 .into_iter()
64 .filter(|c| c.amount.parse::<u128>().is_ok_and(|a| a <= self.0))
65 .collect()
66 }
67}