junobuild_collections/
impls.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::constants::SYS_COLLECTION_PREFIX;
use crate::types::core::CollectionKey;
use crate::types::interface::SetRule;
use crate::types::rules::{Memory, Rule};
use ic_cdk::api::time;
use junobuild_shared::constants::INITIAL_VERSION;
use junobuild_shared::types::state::{Timestamp, Version};

impl Rule {
    pub fn mem(&self) -> Memory {
        self.memory.clone().unwrap_or_default()
    }

    pub fn prepare(
        collection: &CollectionKey,
        current_rule: &Option<&Rule>,
        user_rule: &SetRule,
    ) -> Result<Self, String> {
        if collection.starts_with(SYS_COLLECTION_PREFIX) {
            return Self::prepare_sys_rule(collection, current_rule, user_rule);
        }

        Ok(Self::prepare_user_rule(current_rule, user_rule))
    }

    fn initialize_common_fields(current_rule: &Option<&Rule>) -> (Timestamp, Version, Timestamp) {
        let now = time();

        let created_at: Timestamp = match current_rule {
            None => now,
            Some(current_rule) => current_rule.created_at,
        };

        let version: Version = match current_rule {
            None => INITIAL_VERSION,
            Some(current_rule) => current_rule.version.unwrap_or_default() + 1,
        };

        let updated_at: Timestamp = now;

        (created_at, version, updated_at)
    }

    fn prepare_user_rule(current_rule: &Option<&Rule>, user_rule: &SetRule) -> Self {
        let (created_at, version, updated_at) = Self::initialize_common_fields(current_rule);

        Rule {
            read: user_rule.read.clone(),
            write: user_rule.write.clone(),
            memory: Some(user_rule.clone().memory.unwrap_or(Memory::Stable)),
            mutable_permissions: Some(user_rule.mutable_permissions.unwrap_or(true)),
            max_size: user_rule.max_size,
            max_capacity: user_rule.max_capacity,
            created_at,
            updated_at,
            version: Some(version),
            rate_config: user_rule.rate_config.clone(),
        }
    }

    fn prepare_sys_rule(
        collection: &CollectionKey,
        current_rule: &Option<&Rule>,
        user_rule: &SetRule,
    ) -> Result<Rule, String> {
        match current_rule {
            None => Err(format!("Collection {} is reserved.", collection)),
            Some(current_rule) => {
                let (created_at, version, updated_at) =
                    Self::initialize_common_fields(&Some(current_rule));

                let rule = Rule {
                    read: current_rule.read.clone(),
                    write: current_rule.write.clone(),
                    memory: current_rule.memory.clone(),
                    mutable_permissions: current_rule.mutable_permissions,
                    max_size: current_rule.max_size,
                    max_capacity: current_rule.max_capacity,
                    created_at,
                    updated_at,
                    version: Some(version),
                    rate_config: user_rule.rate_config.clone(),
                };

                Ok(rule)
            }
        }
    }
}