use crate::arena::Arena;
mod inner;
impl<'a> inner::Internable<'a> for str {
type Key = str;
type Container = &'a str;
#[inline]
fn get(this: &&'a str) -> &'a str {
this
}
#[inline]
fn key<'b>(this: &'b &'a str) -> &'b str {
this
}
}
impl<'a> inner::InternAs<'a, str> for &str {
#[inline]
fn key(&self) -> &str {
self
}
#[inline]
fn convert(self, arena: &'a Arena) -> &'a &'a str {
arena.alloc(arena.alloc_str(self))
}
}
pub struct StrInterner<'a> {
inner: inner::Interner<'a, str>,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct InternedStr<'a> {
inner: inner::Interned<'a, str>,
}
impl Default for StrInterner<'_> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<'a> StrInterner<'a> {
pub fn new() -> Self {
Self {
inner: inner::Interner::new(),
}
}
pub fn intern(&self, arena: &'a Arena, value: &str) -> InternedStr<'a> {
InternedStr {
inner: self.inner.intern(arena, value),
}
}
pub fn get_interned(&self, value: &str) -> Option<InternedStr<'a>> {
self.inner
.get_interned(value)
.map(|v| InternedStr { inner: v })
}
}
impl<'a> InternedStr<'a> {
#[inline]
pub fn value(&self) -> &'a str {
self.inner.value()
}
}
impl std::fmt::Debug for InternedStr<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.value().fmt(f)
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub(crate) struct SortedInternedStr<'a>(pub(crate) InternedStr<'a>);
impl PartialOrd for SortedInternedStr<'_> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &Self) -> bool {
self.0.value() < other.0.value()
}
#[inline]
fn le(&self, other: &Self) -> bool {
self.0.value() <= other.0.value()
}
#[inline]
fn gt(&self, other: &Self) -> bool {
self.0.value() > other.0.value()
}
#[inline]
fn ge(&self, other: &Self) -> bool {
self.0.value() >= other.0.value()
}
}
impl Ord for SortedInternedStr<'_> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.value().cmp(other.0.value())
}
}