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