mod convert;
mod cmp;
mod fmt;
mod iter;
mod oct;
mod ops;
mod test;
use core::borrow::{Borrow, BorrowMut};
use core::hash::{Hash, Hasher};
use core::str::{self, FromStr};
use nvec::cold_path;
use nvec::n_vec::{NVec, TryReserveError};
#[derive(Clone)]
pub struct NString<const N: usize>(NVec<u8, N>);
impl<const N: usize> NString<N> {
#[inline]
#[must_use]
pub const fn new() -> Self {
let bytes = NVec::new();
unsafe { Self::from_utf8_unchecked(bytes) }
}
#[inline]
pub const fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
if capacity <= N {
Ok(Self::new())
} else {
Err(TryReserveError)
}
}
pub const fn try_reserve(&self, extra: usize) -> Result<(), TryReserveError> {
self.0.try_reserve(extra)
}
pub const fn try_push(&mut self, c: char) -> Result<(), TryReserveError> {
let mut buf = [0; 4];
let s = c.encode_utf8(&mut buf);
self.try_push_str(s)
}
pub const fn try_push_str(&mut self, s: &str) -> Result<(), TryReserveError> {
if let Err(e) = self.try_reserve(s.len()) {
return Err(e);
}
let slot = {
let base = self.as_mut_ptr();
unsafe { base.add(self.len()) }
};
unsafe { slot.copy_from_nonoverlapping(s.as_ptr(), s.len()); }
unsafe { self.set_len(self.len() + s.len()) };
Ok(())
}
#[inline]
pub const fn truncate(&mut self, len: usize) {
if len >= self.len() {
cold_path();
return;
}
unsafe { self.set_len(len) };
}
#[inline]
pub const fn clear(&mut self) {
self.truncate(0)
}
#[inline]
#[must_use]
pub const fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
#[must_use]
pub const fn remaining_capacity(&self) -> usize {
self.0.remaining_capacity()
}
#[inline(always)]
#[track_caller]
pub const unsafe fn set_len(&mut self, len: usize) {
unsafe { self.0.set_len(len) };
}
#[inline]
#[must_use]
pub const fn len(&self) -> usize {
self.0.len()
}
#[inline]
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline(always)]
#[must_use]
pub const fn copied(&self) -> Self {
let bytes = self.to_bytes();
unsafe { Self::from_utf8_unchecked(bytes) }
}
}
impl<const N: usize> Borrow<str> for NString<N> {
#[inline]
fn borrow(&self) -> &str {
self
}
}
impl<const N: usize> BorrowMut<str> for NString<N> {
#[inline]
fn borrow_mut(&mut self) -> &mut str {
self
}
}
impl<const N: usize> Default for NString<N> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> FromStr for NString<N> {
type Err = TryReserveError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_from_str(s)
}
}
impl<const N: usize> Hash for NString<N> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_str().hash(state);
}
}