miden_protocol/account/interface/
name.rs1use alloc::borrow::Cow;
2use alloc::string::String;
3use core::fmt::Display;
4use core::str::FromStr;
5
6use crate::account::name_validation::{self, NameValidationError};
7use crate::errors::AccountComponentNameError;
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
21pub struct AccountComponentName(Cow<'static, str>);
22
23impl AccountComponentName {
24 pub const fn from_static_str(name: &'static str) -> Self {
34 match name_validation::validate(name) {
35 Ok(()) => Self(Cow::Borrowed(name)),
36 Err(_) => panic!("invalid AccountComponentName: see the type-level documentation"),
37 }
38 }
39
40 pub fn new(name: impl Into<Cow<'static, str>>) -> Result<Self, AccountComponentNameError> {
47 let name = name.into();
48 name_validation::validate(&name).map_err(AccountComponentNameError::from_internal)?;
49 Ok(Self(name))
50 }
51
52 pub fn as_str(&self) -> &str {
57 &self.0
58 }
59}
60
61impl AccountComponentNameError {
62 pub(crate) fn from_internal(error: NameValidationError) -> Self {
65 match error {
66 NameValidationError::TooShort => Self::TooShort,
67 NameValidationError::TooLong => Self::TooLong,
68 NameValidationError::UnexpectedColon => Self::UnexpectedColon,
69 NameValidationError::UnexpectedUnderscore => Self::UnexpectedUnderscore,
70 NameValidationError::InvalidCharacter => Self::InvalidCharacter,
71 }
72 }
73}
74
75impl Display for AccountComponentName {
76 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77 f.write_str(self.as_str())
78 }
79}
80
81impl FromStr for AccountComponentName {
82 type Err = AccountComponentNameError;
83
84 fn from_str(string: &str) -> Result<Self, Self::Err> {
85 Self::new(String::from(string))
86 }
87}
88
89impl TryFrom<&str> for AccountComponentName {
90 type Error = AccountComponentNameError;
91
92 fn try_from(value: &str) -> Result<Self, Self::Error> {
93 value.parse()
94 }
95}
96
97impl TryFrom<String> for AccountComponentName {
98 type Error = AccountComponentNameError;
99
100 fn try_from(value: String) -> Result<Self, Self::Error> {
101 Self::new(value)
102 }
103}
104
105impl From<AccountComponentName> for String {
106 fn from(name: AccountComponentName) -> Self {
107 name.0.into_owned()
108 }
109}
110
111#[cfg(test)]
115mod tests {
116 use super::*;
119
120 #[test]
121 #[should_panic(expected = "invalid AccountComponentName")]
122 fn from_static_str_panics_on_invalid_input() {
123 AccountComponentName::from_static_str("not_two_components");
124 }
125}