use core::fmt;
pub const MAX_SCOPE_VALUE_BYTES: usize = 512;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ScopeValueError {
Empty,
TooLong,
InvalidByte,
}
impl_static_error!(ScopeValueError,
Self::Empty => "authentication scope value is empty",
Self::TooLong => "authentication scope value exceeds the length limit",
Self::InvalidByte => "authentication scope value contains an invalid byte",
);
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ScopeValue<'a>(&'a str);
impl<'a> ScopeValue<'a> {
pub fn new(value: &'a str) -> Result<Self, ScopeValueError> {
if value.is_empty() {
return Err(ScopeValueError::Empty);
}
if value.len() > MAX_SCOPE_VALUE_BYTES {
return Err(ScopeValueError::TooLong);
}
if !value
.bytes()
.all(|byte| byte.is_ascii_graphic() && byte != b'\\')
{
return Err(ScopeValueError::InvalidByte);
}
Ok(Self(value))
}
#[must_use]
pub const fn as_str(self) -> &'a str {
self.0
}
}
impl fmt::Debug for ScopeValue<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("ScopeValue([redacted])")
}
}