use std::{borrow::Cow, fmt, ops::Deref};
use compact_str::CompactString;
#[must_use]
pub fn is_valid(label: &str) -> bool {
label.trim() == label && label.as_bytes().first() != Some(&b'/')
}
#[must_use]
pub fn is_empty(label: &str) -> bool {
debug_assert!(is_valid(label));
label.is_empty()
}
pub trait Label: AsRef<str> + fmt::Debug + Default + PartialEq + Ord + Sized {
#[must_use]
fn from_str(label: &str) -> Self {
Self::from_cow_str(label.into())
}
#[must_use]
fn from_string(label: String) -> Self {
Self::from_cow_str(label.into())
}
#[must_use]
fn from_cow_str(label: Cow<'_, str>) -> Self;
#[must_use]
fn is_valid(&self) -> bool {
is_valid(self.as_ref())
}
#[must_use]
fn is_empty(&self) -> bool {
is_empty(self.as_ref())
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(clippy::module_name_repetitions)]
pub struct CompactLabel(CompactString);
impl CompactLabel {
#[must_use]
pub const fn new(inner: CompactString) -> Self {
Self(inner)
}
}
impl From<CompactString> for CompactLabel {
fn from(from: CompactString) -> Self {
Self::new(from)
}
}
impl From<CompactLabel> for CompactString {
fn from(from: CompactLabel) -> Self {
let CompactLabel(inner) = from;
inner
}
}
impl AsRef<str> for CompactLabel {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Deref for CompactLabel {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl Label for CompactLabel {
fn from_str(label: &str) -> Self {
Self(label.into())
}
fn from_string(label: String) -> Self {
Self(label.into())
}
fn from_cow_str(label: Cow<'_, str>) -> Self {
Self(label.into())
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(clippy::module_name_repetitions)]
pub struct StdLabel(String);
impl StdLabel {
#[must_use]
pub const fn new(inner: String) -> Self {
Self(inner)
}
}
impl From<String> for StdLabel {
fn from(from: String) -> Self {
Self::new(from)
}
}
impl From<StdLabel> for String {
fn from(from: StdLabel) -> Self {
let StdLabel(inner) = from;
inner
}
}
impl AsRef<str> for StdLabel {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Deref for StdLabel {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl Label for StdLabel {
fn from_str(label: &str) -> Self {
Self(label.into())
}
fn from_string(label: String) -> Self {
Self(label)
}
fn from_cow_str(label: Cow<'_, str>) -> Self {
Self(label.into())
}
}