use crate::{config::MAX_INLINE, marker_byte::Marker, ops::GenericString};
use core::{
ops::{Deref, DerefMut},
str::{from_utf8_unchecked, from_utf8_unchecked_mut},
};
#[cfg(target_endian = "little")]
#[repr(C)]
#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
pub(crate) struct InlineString {
pub(crate) marker: Marker,
pub(crate) data: [u8; MAX_INLINE],
}
#[cfg(target_endian = "big")]
#[repr(C)]
#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
pub(crate) struct InlineString {
pub(crate) data: [u8; MAX_INLINE],
pub(crate) marker: Marker,
}
impl Clone for InlineString {
fn clone(&self) -> Self {
unreachable!("InlineString should be copy!")
}
}
impl Copy for InlineString {}
impl Deref for InlineString {
type Target = str;
fn deref(&self) -> &Self::Target {
#[allow(unsafe_code)]
unsafe {
from_utf8_unchecked(&self.data[..self.len()])
}
}
}
impl DerefMut for InlineString {
fn deref_mut(&mut self) -> &mut Self::Target {
let len = self.len();
#[allow(unsafe_code)]
unsafe {
from_utf8_unchecked_mut(&mut self.data[..len])
}
}
}
impl GenericString for InlineString {
fn set_size(&mut self, size: usize) {
self.marker.set_data(size as u8);
}
fn as_mut_capacity_slice(&mut self) -> &mut [u8] {
self.data.as_mut()
}
}
impl InlineString {
pub(crate) const fn new() -> Self {
Self {
marker: Marker::empty(),
data: [0; MAX_INLINE],
}
}
pub(crate) fn len(&self) -> usize {
let len = self.marker.data() as usize;
debug_assert!(len <= MAX_INLINE);
len
}
}
impl From<&str> for InlineString {
fn from(string: &str) -> Self {
let len = string.len();
debug_assert!(len <= MAX_INLINE);
let mut out = Self::new();
out.marker = Marker::new_inline(len as u8);
out.data.as_mut()[..len].copy_from_slice(string.as_bytes());
out
}
}