use std::fmt;
use color_eyre::eyre::eyre;
use super::extension_error;
use crate::error::{BootstrapErrorKind, BootstrapResult};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ExtensionName(String);
impl ExtensionName {
pub fn new(name: impl Into<String>) -> BootstrapResult<Self> {
let value = name.into();
if value.is_empty() || !value.bytes().all(is_name_byte) {
return Err(extension_error(
BootstrapErrorKind::ExtensionConfigInvalid,
eyre!(
"extension name {value:?} is invalid; names use lower-case letters, digits \
and underscores"
),
));
}
Ok(Self(value))
}
#[must_use]
pub fn as_str(&self) -> &str { &self.0 }
}
const fn is_name_byte(byte: u8) -> bool {
byte.is_ascii_lowercase() || byte.is_ascii_digit() || byte == b'_'
}
impl AsRef<str> for ExtensionName {
fn as_ref(&self) -> &str { &self.0 }
}
impl TryFrom<&str> for ExtensionName {
type Error = crate::error::BootstrapError;
fn try_from(value: &str) -> Result<Self, Self::Error> { Self::new(value) }
}
impl fmt::Display for ExtensionName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.0) }
}