use core::{ffi::CStr, fmt::Debug, hash::Hash};
pub unsafe trait Intern: Hash + PartialEq + Eq {
type Primitive: Sized + Copy + Debug;
fn as_bytes(&self) -> &[Self::Primitive];
unsafe fn from_bytes(bytes: &[Self::Primitive]) -> &Self;
}
unsafe impl Intern for str {
type Primitive = u8;
fn as_bytes(&self) -> &[u8] {
str::as_bytes(self)
}
unsafe fn from_bytes(bytes: &[u8]) -> &Self {
unsafe { core::str::from_utf8_unchecked(bytes) }
}
}
unsafe impl Intern for CStr {
type Primitive = u8;
fn as_bytes(&self) -> &[u8] {
CStr::to_bytes_with_nul(self)
}
unsafe fn from_bytes(bytes: &[u8]) -> &Self {
unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }
}
}
unsafe impl Intern for [u8] {
type Primitive = u8;
fn as_bytes(&self) -> &[u8] {
self
}
unsafe fn from_bytes(bytes: &[u8]) -> &Self {
bytes
}
}
unsafe impl Intern for [char] {
type Primitive = char;
fn as_bytes(&self) -> &[char] {
self
}
unsafe fn from_bytes(bytes: &[char]) -> &Self {
bytes
}
}
#[cfg(feature = "std")]
mod std_impls {
use super::Intern;
use std::ffi::OsStr;
unsafe impl Intern for OsStr {
type Primitive = u8;
fn as_bytes(&self) -> &[u8] {
OsStr::as_encoded_bytes(self)
}
unsafe fn from_bytes(bytes: &[u8]) -> &Self {
unsafe { OsStr::from_encoded_bytes_unchecked(bytes) }
}
}
}