Skip to main content

junobuild_cdn/proposals/state/
impls.rs

1use crate::proposals::{Proposal, ProposalKey, ProposalStatus, ProposalType};
2use candid::Principal;
3use ic_cdk::api::time;
4use ic_stable_structures::storable::Bound;
5use ic_stable_structures::Storable;
6use junobuild_shared::serializers::{
7    deserialize_from_bytes, serialize_into_bytes, serialize_to_bytes,
8};
9use junobuild_shared::types::core::Hash;
10use junobuild_shared::types::state::{Version, Versioned};
11use junobuild_shared::version::next_version;
12use std::borrow::Cow;
13
14impl Storable for ProposalKey {
15    fn to_bytes(&self) -> Cow<'_, [u8]> {
16        serialize_to_bytes(self)
17    }
18
19    fn into_bytes(self) -> Vec<u8> {
20        serialize_into_bytes(&self)
21    }
22
23    fn from_bytes(bytes: Cow<[u8]>) -> Self {
24        deserialize_from_bytes(bytes)
25    }
26
27    const BOUND: Bound = Bound::Unbounded;
28}
29
30impl Storable for Proposal {
31    fn to_bytes(&self) -> Cow<'_, [u8]> {
32        serialize_to_bytes(self)
33    }
34
35    fn into_bytes(self) -> Vec<u8> {
36        serialize_into_bytes(&self)
37    }
38
39    fn from_bytes(bytes: Cow<[u8]>) -> Self {
40        deserialize_from_bytes(bytes)
41    }
42
43    const BOUND: Bound = Bound::Unbounded;
44}
45
46impl Proposal {
47    fn get_next_version(current_proposal: &Option<Proposal>) -> Version {
48        next_version(current_proposal)
49    }
50
51    pub fn init(caller: Principal, proposal_type: &ProposalType) -> Self {
52        let now = time();
53
54        let version = Self::get_next_version(&None);
55
56        Proposal {
57            owner: caller,
58            sha256: None,
59            status: ProposalStatus::Initialized,
60            executed_at: None,
61            created_at: now,
62            updated_at: now,
63            version: Some(version),
64            proposal_type: proposal_type.clone(),
65        }
66    }
67
68    pub fn open(current_proposal: &Proposal, sha256: Hash) -> Self {
69        let now = time();
70
71        let version = Self::get_next_version(&Some(current_proposal.clone()));
72
73        Proposal {
74            status: ProposalStatus::Open,
75            sha256: Some(sha256),
76            updated_at: now,
77            version: Some(version),
78            ..current_proposal.clone()
79        }
80    }
81
82    pub fn reject(current_proposal: &Proposal) -> Self {
83        let now = time();
84
85        let version = Self::get_next_version(&Some(current_proposal.clone()));
86
87        Proposal {
88            status: ProposalStatus::Rejected,
89            updated_at: now,
90            version: Some(version),
91            ..current_proposal.clone()
92        }
93    }
94
95    pub fn accept(current_proposal: &Proposal) -> Self {
96        let now = time();
97
98        let version = Self::get_next_version(&Some(current_proposal.clone()));
99
100        Proposal {
101            status: ProposalStatus::Accepted,
102            updated_at: now,
103            version: Some(version),
104            ..current_proposal.clone()
105        }
106    }
107
108    pub fn execute(current_proposal: &Proposal) -> Self {
109        let now = time();
110
111        let version = Self::get_next_version(&Some(current_proposal.clone()));
112
113        Proposal {
114            status: ProposalStatus::Executed,
115            updated_at: now,
116            executed_at: Some(now),
117            version: Some(version),
118            ..current_proposal.clone()
119        }
120    }
121
122    pub fn fail(current_proposal: &Proposal) -> Self {
123        let now = time();
124
125        let version = Self::get_next_version(&Some(current_proposal.clone()));
126
127        Proposal {
128            status: ProposalStatus::Failed,
129            updated_at: now,
130            version: Some(version),
131            ..current_proposal.clone()
132        }
133    }
134}
135
136impl Versioned for Proposal {
137    fn version(&self) -> Option<Version> {
138        self.version
139    }
140}