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