1use crate::{Error, Result};
4use alloc::string::String;
5use core::{
6 fmt::{self, Display},
7 ops::Deref,
8 str::FromStr,
9};
10
11#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
18pub struct KeyName(String);
19
20impl KeyName {
21 pub fn new(name: impl Into<String>) -> Result<Self> {
23 let name = name.into();
24
25 if !name
26 .as_bytes()
27 .iter()
28 .all(|&byte| matches!(byte, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'_'))
29 {
30 return Err(Error::KeyNameInvalid);
31 }
32
33 Ok(Self(name))
34 }
35}
36
37impl AsRef<str> for KeyName {
38 fn as_ref(&self) -> &str {
39 &self.0
40 }
41}
42
43#[cfg(feature = "std")]
44impl AsRef<std::path::Path> for KeyName {
45 fn as_ref(&self) -> &std::path::Path {
46 self.0.as_ref()
47 }
48}
49
50impl Deref for KeyName {
51 type Target = str;
52
53 fn deref(&self) -> &str {
54 &self.0
55 }
56}
57
58impl Display for KeyName {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.write_str(&self.0)
61 }
62}
63
64impl FromStr for KeyName {
65 type Err = Error;
66
67 fn from_str(name: &str) -> Result<Self> {
68 Self::new(name)
69 }
70}