use crate::buffer::{Buffer, CapacityError};
use core::{
cmp::min,
fmt,
ops::{Deref, DerefMut},
};
const STRING_CAP: usize = 256;
#[derive(Eq)]
pub struct String(Buffer<STRING_CAP>);
impl Default for String {
fn default() -> Self {
Self::new()
}
}
impl From<&str> for String {
fn from(s: &str) -> Self {
let mut string = Self::new();
let bytes = s.as_bytes();
let len = min(bytes.len(), STRING_CAP);
let mut end = len;
while end > 0 && !s.is_char_boundary(end) {
end -= 1;
}
let truncated_bytes = &bytes[..end];
string
.extend_from_slice(truncated_bytes)
.unwrap_or_default();
string
}
}
impl String {
#[must_use]
pub const fn new() -> Self {
Self(Buffer::<STRING_CAP>::new())
}
pub fn clear(&mut self) {
self.0.clear();
}
pub fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), CapacityError> {
self.0.extend_from_slice(slice)
}
}
impl Deref for String {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for String {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<[u8]> for String {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl<T: ?Sized> PartialEq<T> for String
where
T: AsRef<[u8]>,
{
fn eq(&self, other: &T) -> bool {
self.as_ref() == other.as_ref()
}
}
impl fmt::Debug for String {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match core::str::from_utf8(self) {
Ok(s) => f.write_str(s),
Err(_) => f.debug_list().entries(self.iter()).finish(),
}
}
}
impl fmt::Display for String {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(core::str::from_utf8(self).unwrap_or(""))
}
}