use std::{
str,
ops::{
Deref,
DerefMut
}
};
use crate::generic::{
Meta,
CalfVec
};
pub struct FromUtf8Error<'a, M: Meta, const N: usize> {
bytes: CalfVec<'a, M, u8, N>,
error: str::Utf8Error
}
impl<'a, M: Meta, const N: usize> FromUtf8Error<'a, M, N> {
pub fn bytes(&self) -> &[u8] {
&self.bytes
}
pub fn utf8_error(&self) -> str::Utf8Error {
self.error
}
}
pub struct CalfString<'a, M: Meta, const N: usize> {
vec: CalfVec<'a, M, u8, N>
}
impl<'a, M: Meta, const N: usize> CalfString<'a, M, N> {
#[inline]
pub fn from_utf8<V: Into<CalfVec<'a, M, u8, N>>>(vec: V) -> Result<CalfString<'a, M, N>, FromUtf8Error<'a, M, N>> {
let vec = vec.into();
match str::from_utf8(&vec) {
Ok(..) => Ok(CalfString { vec }),
Err(e) => Err(FromUtf8Error { bytes: vec, error: e }),
}
}
#[inline]
pub fn len(&self) -> usize {
self.vec.len()
}
#[inline]
pub fn capacity(&self) -> Option<usize> {
self.vec.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.vec.reserve(additional)
}
#[inline]
pub fn push(&mut self, ch: char) {
match ch.len_utf8() {
1 => self.vec.push(ch as u8),
_ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
}
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
&self.vec
}
#[inline]
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
self.vec.truncate(new_len)
}
}
}
impl<'a, M: Meta, const N: usize> Deref for CalfString<'a, M, N> {
type Target = str;
#[inline]
fn deref(&self) -> &str {
unsafe {
std::str::from_utf8_unchecked(&self.vec)
}
}
}
impl<'a, M: Meta, const N: usize> DerefMut for CalfString<'a, M, N> {
#[inline]
fn deref_mut(&mut self) -> &mut str {
unsafe {
std::str::from_utf8_unchecked_mut(&mut self.vec)
}
}
}