Skip to main content

canic_template_types/ids/
mod.rs

1use candid::{
2    CandidType,
3    types::{Serializer, Type},
4};
5use canic_memory::impl_storable_bounded;
6pub use canic_types::CanisterRole;
7use serde::{Deserialize, Serialize};
8use std::{borrow::Borrow, borrow::Cow, fmt};
9
10///
11/// TemplateId
12///
13
14#[derive(
15    CandidType, Clone, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
16)]
17#[serde(transparent)]
18pub struct TemplateId(pub Cow<'static, str>);
19
20impl TemplateId {
21    #[must_use]
22    pub const fn new(s: &'static str) -> Self {
23        Self(Cow::Borrowed(s))
24    }
25
26    #[must_use]
27    pub const fn owned(s: String) -> Self {
28        Self(Cow::Owned(s))
29    }
30
31    #[must_use]
32    pub fn as_str(&self) -> &str {
33        &self.0
34    }
35}
36
37impl From<&'static str> for TemplateId {
38    fn from(value: &'static str) -> Self {
39        Self::new(value)
40    }
41}
42
43impl From<String> for TemplateId {
44    fn from(value: String) -> Self {
45        Self::owned(value)
46    }
47}
48
49impl From<&String> for TemplateId {
50    fn from(value: &String) -> Self {
51        Self::owned(value.clone())
52    }
53}
54
55impl Borrow<str> for TemplateId {
56    fn borrow(&self) -> &str {
57        self.as_str()
58    }
59}
60
61impl fmt::Display for TemplateId {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        f.write_str(self.as_str())
64    }
65}
66
67impl_storable_bounded!(TemplateId, 160, false);
68
69///
70/// TemplateVersion
71///
72
73#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
74#[serde(transparent)]
75pub struct TemplateVersion(pub Cow<'static, str>);
76
77impl TemplateVersion {
78    #[must_use]
79    pub const fn new(s: &'static str) -> Self {
80        Self(Cow::Borrowed(s))
81    }
82
83    #[must_use]
84    pub const fn owned(s: String) -> Self {
85        Self(Cow::Owned(s))
86    }
87
88    #[must_use]
89    pub fn as_str(&self) -> &str {
90        &self.0
91    }
92}
93
94impl From<&'static str> for TemplateVersion {
95    fn from(value: &'static str) -> Self {
96        Self::new(value)
97    }
98}
99
100impl From<String> for TemplateVersion {
101    fn from(value: String) -> Self {
102        Self::owned(value)
103    }
104}
105
106impl From<&String> for TemplateVersion {
107    fn from(value: &String) -> Self {
108        Self::owned(value.clone())
109    }
110}
111
112impl Borrow<str> for TemplateVersion {
113    fn borrow(&self) -> &str {
114        self.as_str()
115    }
116}
117
118impl fmt::Display for TemplateVersion {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        f.write_str(self.as_str())
121    }
122}
123
124impl CandidType for TemplateVersion {
125    fn _ty() -> Type {
126        String::ty()
127    }
128
129    fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
130    where
131        S: Serializer,
132    {
133        self.as_str().idl_serialize(serializer)
134    }
135}
136
137impl_storable_bounded!(TemplateVersion, 64, false);
138
139///
140/// WasmStoreBinding
141///
142
143#[derive(
144    CandidType, Clone, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
145)]
146#[serde(transparent)]
147pub struct WasmStoreBinding(pub Cow<'static, str>);
148
149impl WasmStoreBinding {
150    #[must_use]
151    pub const fn new(s: &'static str) -> Self {
152        Self(Cow::Borrowed(s))
153    }
154
155    #[must_use]
156    pub const fn owned(s: String) -> Self {
157        Self(Cow::Owned(s))
158    }
159
160    #[must_use]
161    pub fn as_str(&self) -> &str {
162        &self.0
163    }
164}
165
166impl From<&'static str> for WasmStoreBinding {
167    fn from(value: &'static str) -> Self {
168        Self::new(value)
169    }
170}
171
172impl From<String> for WasmStoreBinding {
173    fn from(value: String) -> Self {
174        Self::owned(value)
175    }
176}
177
178impl From<&String> for WasmStoreBinding {
179    fn from(value: &String) -> Self {
180        Self::owned(value.clone())
181    }
182}
183
184impl Borrow<str> for WasmStoreBinding {
185    fn borrow(&self) -> &str {
186        self.as_str()
187    }
188}
189
190impl fmt::Display for WasmStoreBinding {
191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192        f.write_str(self.as_str())
193    }
194}
195
196impl_storable_bounded!(WasmStoreBinding, 64, false);
197
198///
199/// TemplateReleaseKey
200///
201
202#[derive(
203    CandidType, Clone, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
204)]
205pub struct TemplateReleaseKey {
206    pub template_id: TemplateId,
207    pub version: TemplateVersion,
208}
209
210impl TemplateReleaseKey {
211    #[must_use]
212    pub const fn new(template_id: TemplateId, version: TemplateVersion) -> Self {
213        Self {
214            template_id,
215            version,
216        }
217    }
218}
219
220impl fmt::Display for TemplateReleaseKey {
221    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222        write!(f, "{}@{}", self.template_id, self.version)
223    }
224}
225
226impl_storable_bounded!(TemplateReleaseKey, 256, false);
227
228///
229/// TemplateChunkKey
230///
231
232#[derive(
233    CandidType, Clone, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
234)]
235pub struct TemplateChunkKey {
236    pub release: TemplateReleaseKey,
237    pub chunk_index: u32,
238}
239
240impl TemplateChunkKey {
241    #[must_use]
242    pub const fn new(release: TemplateReleaseKey, chunk_index: u32) -> Self {
243        Self {
244            release,
245            chunk_index,
246        }
247    }
248}
249
250impl fmt::Display for TemplateChunkKey {
251    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252        write!(f, "{}#{}", self.release, self.chunk_index)
253    }
254}
255
256impl_storable_bounded!(TemplateChunkKey, 320, false);
257
258#[cfg(test)]
259mod tests {
260    use super::{CanisterRole, TemplateVersion};
261    use candid::{CandidType, Encode};
262
263    #[test]
264    fn canister_role_basic_traits_and_utils() {
265        let a = CanisterRole::ROOT;
266        assert!(a.is_root());
267        assert_eq!(a.as_str(), "root");
268        let b: CanisterRole = "example".into();
269        assert_eq!(b.as_str(), "example");
270        let s: String = b.clone().into();
271        assert_eq!(s, "example");
272        assert_eq!(b.as_ref(), "example");
273    }
274
275    #[test]
276    fn template_version_uses_string_candid_encoding() {
277        let version = TemplateVersion::new("0.18.5");
278
279        assert_eq!(TemplateVersion::ty(), String::ty());
280        assert_eq!(Encode!(&version).unwrap(), Encode!(&"0.18.5").unwrap());
281    }
282}
283
284///
285/// TemplateChunkingMode
286///
287
288#[derive(
289    CandidType, Clone, Copy, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq,
290)]
291pub enum TemplateChunkingMode {
292    Inline,
293    Chunked,
294}
295
296///
297/// WasmStoreGcMode
298///
299
300#[derive(
301    CandidType, Clone, Copy, Debug, Default, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq,
302)]
303pub enum WasmStoreGcMode {
304    #[default]
305    Normal,
306    Prepared,
307    InProgress,
308    Complete,
309}
310
311///
312/// WasmStoreGcStatus
313///
314
315#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
316pub struct WasmStoreGcStatus {
317    pub mode: WasmStoreGcMode,
318    pub changed_at: u64,
319    pub prepared_at: Option<u64>,
320    pub started_at: Option<u64>,
321    pub completed_at: Option<u64>,
322    pub runs_completed: u32,
323}
324
325///
326/// TemplateManifestState
327///
328
329#[derive(
330    CandidType, Clone, Copy, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq,
331)]
332pub enum TemplateManifestState {
333    Staged,
334    Approved,
335    Blocked,
336    Deprecated,
337}