templar_vault_kernel/restrictions/
mod.rs1#[cfg(any(feature = "borsh-schema", feature = "schemars"))]
6use alloc::string::ToString;
7use alloc::vec::Vec;
8#[cfg(feature = "schemars")]
9use alloc::{borrow::ToOwned, boxed::Box, vec};
10
11use crate::types::Address;
12use derive_more::IsVariant;
13
14fn normalize_addresses(mut addresses: Vec<Address>) -> Vec<Address> {
15 let mut deduped = Vec::with_capacity(addresses.len());
16 for address in addresses.drain(..) {
17 if !deduped.contains(&address) {
18 deduped.push(address);
19 }
20 }
21 deduped
22}
23
24#[templar_vault_macros::vault_derive(borsh_schema, schemars)]
27#[derive(Clone, Copy, PartialEq, Eq)]
28pub enum RestrictionKind {
29 Paused,
31 Blacklisted,
33 NotWhitelisted,
35}
36
37#[templar_vault_macros::vault_derive(borsh, borsh_schema, schemars, serde)]
38#[derive(Clone, PartialEq, Eq, IsVariant)]
39pub enum RestrictionMode {
40 #[cfg_attr(feature = "serde", serde(rename = "BlackList"))]
42 Blacklist(Vec<Address>),
43 #[cfg_attr(feature = "serde", serde(rename = "WhiteList"))]
45 Whitelist(Vec<Address>),
46}
47
48pub type Restrictions = RestrictionMode;
49
50impl RestrictionMode {
51 #[must_use]
52 pub fn blacklist(addresses: Vec<Address>) -> Self {
53 Self::Blacklist(normalize_addresses(addresses))
54 }
55
56 #[must_use]
57 pub fn whitelist(addresses: Vec<Address>) -> Self {
58 Self::Whitelist(normalize_addresses(addresses))
59 }
60
61 #[must_use]
62 pub fn normalized(self) -> Self {
63 match self {
64 Self::Blacklist(addresses) => Self::Blacklist(normalize_addresses(addresses)),
65 Self::Whitelist(addresses) => Self::Whitelist(normalize_addresses(addresses)),
66 }
67 }
68
69 pub fn is_restricted(&self, actor_id: &Address) -> Option<RestrictionKind> {
77 match self {
78 Self::Blacklist(blacklist) => {
79 if blacklist.contains(actor_id) {
80 Some(RestrictionKind::Blacklisted)
81 } else {
82 None
83 }
84 }
85 Self::Whitelist(whitelist) => {
86 if whitelist.contains(actor_id) {
87 None
88 } else {
89 Some(RestrictionKind::NotWhitelisted)
90 }
91 }
92 }
93 }
94
95 #[must_use]
96 pub fn is_restricted_allowing_self(
97 &self,
98 actor_id: &Address,
99 self_id: &Address,
100 ) -> Option<RestrictionKind> {
101 match self {
102 Self::Whitelist(_) if actor_id == self_id => None,
103 _ => self.is_restricted(actor_id),
104 }
105 }
106
107 }
109
110#[cfg(test)]
111mod tests;