junobuild_collections/
impls.rs

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