1use crate::impl_storable_bounded;
8use candid::CandidType;
9use derive_more::Display;
10use serde::{Deserialize, Serialize};
11use std::{borrow::Borrow, borrow::Cow, str::FromStr};
12
13#[derive(
23 CandidType, Clone, Debug, Eq, Ord, Display, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
24)]
25#[serde(transparent)]
26pub struct CanisterType(pub Cow<'static, str>);
27
28impl CanisterType {
29 pub const ROOT: Self = Self(Cow::Borrowed("root"));
30
31 #[must_use]
32 pub const fn new(s: &'static str) -> Self {
33 Self(Cow::Borrowed(s))
34 }
35
36 #[must_use]
37 pub const fn owned(s: String) -> Self {
38 Self(Cow::Owned(s))
39 }
40
41 #[must_use]
42 pub fn as_str(&self) -> &str {
43 &self.0
44 }
45
46 #[must_use]
48 pub fn is_root(&self) -> bool {
49 self.0.as_ref() == "root"
50 }
51
52 #[must_use]
54 pub fn into_string(self) -> String {
55 self.0.into_owned()
56 }
57}
58
59impl FromStr for CanisterType {
60 type Err = String;
61
62 fn from_str(s: &str) -> Result<Self, Self::Err> {
63 Ok(Self::owned(s.to_string()))
64 }
65}
66
67impl From<&'static str> for CanisterType {
68 fn from(s: &'static str) -> Self {
69 Self(Cow::Borrowed(s))
70 }
71}
72
73impl From<&String> for CanisterType {
74 fn from(s: &String) -> Self {
75 Self(Cow::Owned(s.clone()))
76 }
77}
78
79impl From<String> for CanisterType {
80 fn from(s: String) -> Self {
81 Self(Cow::Owned(s))
82 }
83}
84
85impl From<CanisterType> for String {
86 fn from(ct: CanisterType) -> Self {
87 ct.into_string()
88 }
89}
90
91impl AsRef<str> for CanisterType {
92 fn as_ref(&self) -> &str {
93 self.as_str()
94 }
95}
96
97impl Borrow<str> for CanisterType {
98 fn borrow(&self) -> &str {
99 self.as_str()
100 }
101}
102
103impl_storable_bounded!(CanisterType, 64, false);
104
105#[cfg(test)]
110mod tests {
111 use super::CanisterType;
112 #[test]
113 fn basic_traits_and_utils() {
114 let a = CanisterType::ROOT;
115 assert!(a.is_root());
116 assert_eq!(a.as_str(), "root");
117 let b: CanisterType = "example".into();
118 assert_eq!(b.as_str(), "example");
119 let s: String = b.clone().into();
120 assert_eq!(s, "example");
121 assert_eq!(b.as_ref(), "example");
122 }
123}