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