junobuild_collections/
impls.rs

1use crate::assert::collection::is_system_collection;
2use crate::errors::JUNO_COLLECTIONS_ERROR_RESERVED_COLLECTION;
3use crate::types::core::CollectionKey;
4use crate::types::interface::SetRule;
5use crate::types::rules::{Memory, Rule};
6use ic_cdk::api::time;
7use junobuild_shared::types::state::{Timestamp, Version, Versioned};
8use junobuild_shared::version::next_version;
9
10impl Rule {
11    pub fn mem(&self) -> Memory {
12        self.memory.clone().unwrap_or_default()
13    }
14
15    pub fn prepare(
16        collection: &CollectionKey,
17        current_rule: &Option<&Rule>,
18        user_rule: &SetRule,
19    ) -> Result<Self, String> {
20        if is_system_collection(collection) {
21            return Self::prepare_sys_rule(collection, current_rule, user_rule);
22        }
23
24        Ok(Self::prepare_user_rule(current_rule, user_rule))
25    }
26
27    fn initialize_common_fields(current_rule: &Option<&Rule>) -> (Timestamp, Version, Timestamp) {
28        let now = time();
29
30        let created_at: Timestamp = match current_rule {
31            None => now,
32            Some(current_rule) => current_rule.created_at,
33        };
34
35        let version = next_version(current_rule);
36
37        let updated_at: Timestamp = now;
38
39        (created_at, version, updated_at)
40    }
41
42    fn prepare_user_rule(current_rule: &Option<&Rule>, user_rule: &SetRule) -> Self {
43        let (created_at, version, updated_at) = Self::initialize_common_fields(current_rule);
44
45        Rule {
46            read: user_rule.read.clone(),
47            write: user_rule.write.clone(),
48            memory: Some(user_rule.clone().memory.unwrap_or(Memory::Stable)),
49            mutable_permissions: Some(user_rule.mutable_permissions.unwrap_or(true)),
50            max_size: user_rule.max_size,
51            max_capacity: user_rule.max_capacity,
52            max_changes_per_user: user_rule.max_changes_per_user,
53            created_at,
54            updated_at,
55            version: Some(version),
56            rate_config: user_rule.rate_config.clone(),
57        }
58    }
59
60    fn prepare_sys_rule(
61        collection: &CollectionKey,
62        current_rule: &Option<&Rule>,
63        user_rule: &SetRule,
64    ) -> Result<Rule, String> {
65        match current_rule {
66            None => Err(format!(
67                "{} ({})",
68                JUNO_COLLECTIONS_ERROR_RESERVED_COLLECTION, collection
69            )),
70            Some(current_rule) => {
71                let (created_at, version, updated_at) =
72                    Self::initialize_common_fields(&Some(current_rule));
73
74                let rule = Rule {
75                    read: current_rule.read.clone(),
76                    write: current_rule.write.clone(),
77                    memory: current_rule.memory.clone(),
78                    mutable_permissions: current_rule.mutable_permissions,
79                    max_size: current_rule.max_size,
80                    max_capacity: current_rule.max_capacity,
81                    max_changes_per_user: current_rule.max_changes_per_user,
82                    created_at,
83                    updated_at,
84                    version: Some(version),
85                    rate_config: user_rule.rate_config.clone(),
86                };
87
88                Ok(rule)
89            }
90        }
91    }
92}
93
94impl Versioned for &Rule {
95    fn version(&self) -> Option<Version> {
96        self.version
97    }
98}