use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct StrRef {
parent: Arc<str>,
start: u32,
end: u32,
}
impl StrRef {
#[inline]
pub fn from_arc(parent: Arc<str>) -> Self {
let end = parent.len() as u32;
Self { parent, start: 0, end }
}
#[inline]
pub fn slice(parent: Arc<str>, start: usize, end: usize) -> Self {
debug_assert!(start <= end);
debug_assert!(end <= parent.len());
debug_assert!(parent.is_char_boundary(start));
debug_assert!(parent.is_char_boundary(end));
Self {
parent,
start: start as u32,
end: end as u32,
}
}
#[inline] pub fn as_str(&self) -> &str {
&self.parent[self.start as usize .. self.end as usize]
}
#[inline] pub fn len(&self) -> usize { (self.end - self.start) as usize }
#[inline] pub fn is_empty(&self) -> bool { self.end == self.start }
#[inline]
pub fn to_arc(&self) -> Arc<str> {
if self.start == 0 && self.end as usize == self.parent.len() {
Arc::clone(&self.parent)
} else {
Arc::<str>::from(self.as_str())
}
}
}
impl AsRef<str> for StrRef {
#[inline] fn as_ref(&self) -> &str { self.as_str() }
}
impl std::ops::Deref for StrRef {
type Target = str;
#[inline] fn deref(&self) -> &str { self.as_str() }
}
impl std::fmt::Display for StrRef {
#[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl PartialEq for StrRef {
#[inline] fn eq(&self, other: &Self) -> bool { self.as_str() == other.as_str() }
}
impl Eq for StrRef {}
impl PartialEq<str> for StrRef {
#[inline] fn eq(&self, other: &str) -> bool { self.as_str() == other }
}
impl PartialEq<&str> for StrRef {
#[inline] fn eq(&self, other: &&str) -> bool { self.as_str() == *other }
}
impl PartialEq<Arc<str>> for StrRef {
#[inline] fn eq(&self, other: &Arc<str>) -> bool { self.as_str() == other.as_ref() }
}
impl std::hash::Hash for StrRef {
#[inline] fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_str().hash(state)
}
}
impl From<Arc<str>> for StrRef {
#[inline] fn from(a: Arc<str>) -> Self { Self::from_arc(a) }
}
impl From<&str> for StrRef {
#[inline] fn from(s: &str) -> Self { Self::from_arc(Arc::<str>::from(s)) }
}
impl From<String> for StrRef {
#[inline] fn from(s: String) -> Self { Self::from_arc(Arc::<str>::from(s)) }
}