1use crate::{cdk::candid::CandidType, impl_storable_bounded};
8use serde::{Deserialize, Serialize};
9use std::{
10 borrow::{Borrow, Cow},
11 fmt,
12 str::FromStr,
13};
14
15const PRIME_ROLE: &str = "prime";
26
27#[derive(
28 CandidType, Clone, Debug, Eq, Ord, PartialOrd, Deserialize, Serialize, PartialEq, Hash,
29)]
30#[serde(transparent)]
31pub struct SubnetRole(pub Cow<'static, str>);
32
33impl SubnetRole {
34 pub const PRIME: Self = Self(Cow::Borrowed(PRIME_ROLE));
35
36 #[must_use]
38 pub const fn new(s: &'static str) -> Self {
39 Self(Cow::Borrowed(s))
40 }
41
42 #[must_use]
44 pub const fn owned(s: String) -> Self {
45 Self(Cow::Owned(s))
46 }
47
48 #[must_use]
50 pub fn as_str(&self) -> &str {
51 &self.0
52 }
53
54 #[must_use]
56 pub fn is_prime(&self) -> bool {
57 self.0.as_ref() == PRIME_ROLE
58 }
59
60 #[must_use]
62 pub fn into_string(self) -> String {
63 self.0.into_owned()
64 }
65}
66
67impl FromStr for SubnetRole {
68 type Err = String;
69
70 fn from_str(s: &str) -> Result<Self, Self::Err> {
71 Ok(Self::owned(s.to_string()))
72 }
73}
74
75impl From<&'static str> for SubnetRole {
76 fn from(s: &'static str) -> Self {
77 Self(Cow::Borrowed(s))
78 }
79}
80
81impl From<&String> for SubnetRole {
82 fn from(s: &String) -> Self {
83 Self(Cow::Owned(s.clone()))
84 }
85}
86
87impl From<String> for SubnetRole {
88 fn from(s: String) -> Self {
89 Self(Cow::Owned(s))
90 }
91}
92
93impl From<SubnetRole> for String {
94 fn from(ct: SubnetRole) -> Self {
95 ct.into_string()
96 }
97}
98
99impl AsRef<str> for SubnetRole {
100 fn as_ref(&self) -> &str {
101 self.as_str()
102 }
103}
104
105impl Borrow<str> for SubnetRole {
106 fn borrow(&self) -> &str {
107 self.as_str()
108 }
109}
110
111impl fmt::Display for SubnetRole {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 f.write_str(self.as_str())
114 }
115}
116
117impl_storable_bounded!(SubnetRole, 64, false);
118
119#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn basic_traits_and_utils() {
129 let a = SubnetRole::PRIME;
130 assert!(a.is_prime());
131 assert_eq!(a.as_str(), "prime");
132 let b: SubnetRole = "example".into();
133 assert_eq!(b.as_str(), "example");
134 let s: String = b.clone().into();
135 assert_eq!(s, "example");
136 assert_eq!(b.as_ref(), "example");
137 }
138}