junobuild_collections/
impls.rs1use 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 "{JUNO_COLLECTIONS_ERROR_RESERVED_COLLECTION} ({collection})"
68 )),
69 Some(current_rule) => {
70 let (created_at, version, updated_at) =
71 Self::initialize_common_fields(&Some(current_rule));
72
73 let rule = Rule {
74 read: current_rule.read.clone(),
75 write: current_rule.write.clone(),
76 memory: current_rule.memory.clone(),
77 mutable_permissions: current_rule.mutable_permissions,
78 max_size: current_rule.max_size,
79 max_capacity: current_rule.max_capacity,
80 max_changes_per_user: current_rule.max_changes_per_user,
81 created_at,
82 updated_at,
83 version: Some(version),
84 rate_config: user_rule.rate_config.clone(),
85 };
86
87 Ok(rule)
88 }
89 }
90 }
91
92 pub fn switch_rule_memory(current_rule: &Rule) -> Rule {
93 let (created_at, version, updated_at) = Self::initialize_common_fields(&Some(current_rule));
94
95 Rule {
96 memory: Some(match current_rule.mem() {
97 Memory::Heap => Memory::Stable,
98 Memory::Stable => Memory::Heap,
99 }),
100 created_at,
101 updated_at,
102 version: Some(version),
103 ..current_rule.clone()
104 }
105 }
106}
107
108impl Versioned for &Rule {
109 fn version(&self) -> Option<Version> {
110 self.version
111 }
112}