use std::{borrow::Cow, error, fmt};
use aliri_braid::braid;
use smartstring::alias::String;
#[braid(serde, ref_doc = "A borrowed reference to a string slice wrapper")]
pub struct SmartUsernameBuf;
#[braid(serde, no_expose)]
pub struct CompactData(compact_str::CompactString);
#[braid(
serde,
no_expose,
normalizer,
ref_doc = "A borrowed reference to a non-empty, lowercase string"
)]
pub struct LowerCompactString(compact_str::CompactString);
impl aliri_braid::Validator for LowerCompactString {
type Error = InvalidString;
fn validate(raw: &str) -> Result<(), Self::Error> {
if raw.is_empty() {
Err(InvalidString::EmptyString)
} else if raw.chars().any(char::is_uppercase) {
Err(InvalidString::InvalidCharacter)
} else {
Ok(())
}
}
}
impl aliri_braid::Normalizer for LowerCompactString {
fn normalize(s: &str) -> Result<Cow<str>, Self::Error> {
if s.is_empty() {
Err(InvalidString::EmptyString)
} else if s.contains(char::is_uppercase) {
Ok(Cow::Owned(s.to_lowercase()))
} else {
Ok(Cow::Borrowed(s))
}
}
}
#[derive(Debug)]
pub enum InvalidString {
EmptyString,
InvalidCharacter,
}
impl fmt::Display for InvalidString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::EmptyString => f.write_str("string cannot be empty"),
Self::InvalidCharacter => f.write_str("string contains invalid uppercase character"),
}
}
}
impl error::Error for InvalidString {}
aliri_braid::from_infallible!(InvalidString);