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