#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(unused_parens)]
#![allow(unused_assignments)]
#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(dead_code)]
use crate::{str12, str128, str16, str192, str24, str256, str32, str4, str48, str64, str8, str96,zstr};
use core::cmp::{min, Ordering};
use core::ops::{Add,Range,Index,IndexMut,RangeFull,RangeFrom,RangeTo};
use core::ops::{RangeInclusive,RangeToInclusive};
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct tstr<const N: usize = 256> {
chrs: [u8; N],
}
impl<const N: usize> tstr<N> {
pub fn make(s: &str) -> tstr<N> {
let mut chars = [0u8; N];
let bytes = s.as_bytes(); let blen = bytes.len();
if (blen >= N) {
panic!("!Fixedstr Warning in str::make: length of string literal \"{}\" exceeds the capacity of type str{}; string truncated",s,N);
}
let limit = min(N - 1, blen);
chars[1..limit + 1].copy_from_slice(&bytes[..limit]);
chars[0] = limit as u8;
if chars[0] == 0 {
chars[0] = blen as u8;
}
tstr { chrs: chars }
}
pub fn create(s: &str) -> tstr<N> {
let mut chars = [0u8; N];
let bytes = s.as_bytes();
let blen = bytes.len();
let limit = min(N - 1, blen);
chars[1..limit + 1].copy_from_slice(&bytes[..limit]);
chars[0] = limit as u8;
if chars[0] == 0 {
chars[0] = blen as u8;
}
tstr { chrs: chars }
}
pub fn try_make(s: &str) -> Result<tstr<N>, &str> {
if s.len() > N - 1 {
Err(s)
} else {
Ok(tstr::make(s))
}
}
pub fn new() -> tstr<N> {
tstr::make("")
}
pub fn len(&self) -> usize {
self.chrs[0] as usize
}
pub fn charlen(&self) -> usize {
self.to_str().chars().count()
}
pub fn capacity(&self) -> usize {
N - 1
}
pub fn as_bytes(&self) -> &[u8] {
&self.chrs[1..self.len() + 1]
}
pub fn to_str(&self) -> &str {
unsafe { core::str::from_utf8_unchecked(&self.chrs[1..self.len() + 1]) }
}
pub fn as_str(&self) -> &str {
core::str::from_utf8(&self.chrs[1..self.len() + 1]).unwrap()
}
pub fn set(&mut self, i: usize, c: char) -> bool {
let ref mut cbuf = [0u8; 4];
c.encode_utf8(cbuf);
let clen = c.len_utf8();
if let Some((bi, rc)) = self.to_str().char_indices().nth(i) {
if clen == rc.len_utf8() {
self.chrs[bi + 1..bi + clen + 1].copy_from_slice(&cbuf[..clen]);
return true;
}
}
return false;
} pub fn push<'t>(&mut self, s: &'t str) -> &'t str {
if s.len() < 1 {
return s;
}
let mut buf = [0u8; 4];
let mut i = self.len();
let mut sci = 0; for c in s.chars() {
let clen = c.len_utf8();
c.encode_utf8(&mut buf);
if i+clen+1 <= N {
self.chrs[i+1 .. i+clen+1].copy_from_slice(&buf[..clen]);
i += clen;
} else {
self.chrs[0] = i as u8;
return &s[sci..];
}
sci += clen;
}
if i < N {
self.chrs[0] = i as u8;
} &s[sci..]
}
pub fn push_str<'t>(&mut self, s: &'t str) -> &'t str {
self.push(s)
}
pub fn nth(&self, n: usize) -> Option<char> {
self.to_str().chars().nth(n)
}
pub fn nth_ascii(&self, n: usize) -> char {
self.chrs[n + 1] as char
}
pub fn is_ascii(&self) -> bool {
self.to_str().is_ascii()
}
pub fn truncate(&mut self, n: usize) {
if let Some((bi, c)) = self.to_str().char_indices().nth(n) {
self.chrs[0] = bi as u8;
}
}
pub fn truncate_bytes(&mut self, n: usize) {
if (n<self.chrs[0] as usize) {
assert!(self.is_char_boundary(n));
self.chrs[0] = n as u8;
}
}
pub fn clear(&mut self) {
self.chrs[0]=0;
}
pub fn make_ascii_lowercase(&mut self) {
let end = (self.chrs[0] as usize)+1;
for b in &mut self.chrs[1..end] {
if *b>=65 && *b<=90 { *b |= 32; }
}
}
pub fn make_ascii_uppercase(&mut self) {
let end = (self.chrs[0] as usize)+1;
for b in &mut self.chrs[1..end] {
if *b>=97 && *b<=122 { *b -= 32; }
}
}
pub fn to_ascii_upper(&self) -> Self
{
let mut cp = self.clone();
cp.make_ascii_uppercase();
cp
}
pub fn to_ascii_lower(&self) -> Self
{
let mut cp = *self;
cp.make_ascii_lowercase();
cp
}
}
impl<const N:usize> core::ops::Deref for tstr<N>
{
type Target = str;
fn deref(&self) -> &Self::Target {
self.to_str()
}
}
impl<const N: usize> core::convert::AsRef<str> for tstr<N> {
fn as_ref(&self) -> &str {
self.to_str()
}
}
impl<const N: usize> core::convert::AsMut<str> for tstr<N> {
fn as_mut(&mut self) -> &mut str {
let blen = self.len() + 1;
unsafe { core::str::from_utf8_unchecked_mut(&mut self.chrs[1..blen]) }
}
}
impl<T: AsRef<str> + ?Sized, const N: usize> core::convert::From<&T> for tstr<N> {
fn from(s: &T) -> tstr<N> {
tstr::create(s.as_ref())
}
}
impl<T: AsMut<str> + ?Sized, const N: usize> core::convert::From<&mut T> for tstr<N> {
fn from(s: &mut T) -> tstr<N> {
tstr::create(s.as_mut())
}
}
impl<const N: usize, const M: usize> core::convert::From<zstr<M>> for tstr<N> {
fn from(s: zstr<M>) -> tstr<N> {
tstr::<N>::create(s.to_str())
}
}
impl<const N: usize> core::cmp::PartialOrd for tstr<N> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<const N: usize> core::cmp::Ord for tstr<N> {
fn cmp(&self, other: &Self) -> Ordering {
self.chrs[1..self.len() + 1].cmp(&other.chrs[1..other.len() + 1])
}
}
impl<const M: usize> tstr<M> {
pub fn resize<const N: usize>(&self) -> tstr<N> {
let slen = self.len();
let length = if (slen < N - 1) { slen } else { N - 1 };
let mut chars = [0u8; N];
chars[1..length + 1].copy_from_slice(&self.chrs[1..length + 1]);
chars[0] = (length) as u8;
tstr { chrs: chars }
}
pub fn reallocate<const N: usize>(&self) -> Option<tstr<N>> {
if self.len() < N {
Some(self.resize())
} else {
None
}
} }
impl<const N: usize> core::fmt::Display for tstr<N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.to_str())
}
}
impl<const N: usize> PartialEq<&str> for tstr<N> {
fn eq(&self, other: &&str) -> bool {
self.to_str() == *other } }
impl<const N: usize> PartialEq<&str> for &tstr<N> {
fn eq(&self, other: &&str) -> bool {
&self.to_str() == other
} }
impl<'t, const N: usize> PartialEq<tstr<N>> for &'t str {
fn eq(&self, other: &tstr<N>) -> bool {
&other.to_str() == self
}
}
impl<'t, const N: usize> PartialEq<&tstr<N>> for &'t str {
fn eq(&self, other: &&tstr<N>) -> bool {
&other.to_str() == self
}
}
impl<const N: usize> Default for tstr<N> {
fn default() -> Self {
tstr::<N>::make("")
}
}
impl<const N: usize, const M: usize> PartialEq<zstr<N>> for tstr<M> {
fn eq(&self, other: &zstr<N>) -> bool {
other.to_str() == self.to_str()
}
}
impl<const N: usize, const M: usize> PartialEq<&zstr<N>> for tstr<M> {
fn eq(&self, other: &&zstr<N>) -> bool {
other.to_str() == self.to_str()
}
}
impl<const N: usize> core::fmt::Debug for tstr<N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.pad(&self.to_str())
}
}
impl<IndexType, const N: usize> core::ops::Index<IndexType> for tstr<N>
where
IndexType: core::slice::SliceIndex<str>,
{
type Output = IndexType::Output;
fn index(&self, index: IndexType) -> &Self::Output {
&self.to_str()[index]
}
}
impl<const N: usize> tstr<N> {
pub fn substr(&self, start: usize, end: usize) -> tstr<N> {
let mut chars = [0u8; N];
let mut inds = self.char_indices();
let len = self.len();
if start >= len || end <= start {
return tstr { chrs: chars };
}
chars[0] = (end - start) as u8;
let (si, _) = inds.nth(start).unwrap();
let last = if (end >= len) {
len
} else {
match inds.nth(end - start - 1) {
Some((ei, _)) => ei,
None => len,
} }; chars[1..last - si + 1].copy_from_slice(&self.chrs[si + 1..last + 1]);
tstr { chrs: chars }
} }
impl Add for str8 {
type Output = str16;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str16 {
type Output = str32;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str32 {
type Output = str64;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str64 {
type Output = str128;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str128 {
type Output = str256;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str4 {
type Output = str8;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str12 {
type Output = str24;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str24 {
type Output = str48;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str48 {
type Output = str96;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl Add for str96 {
type Output = str192;
fn add(self, other: Self) -> Self::Output {
let mut cat: Self::Output = self.resize();
let slen = self.len();
let olen = other.len();
cat.chrs[slen + 1..slen + olen + 1].copy_from_slice(&other.chrs[1..olen + 1]);
cat.chrs[0] = (slen + olen) as u8;
cat
}
}
impl<const N: usize> core::fmt::Write for tstr<N> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
if s.len() + self.len() > N - 1 {
return Err(core::fmt::Error::default());
}
self.push(s);
Ok(())
} }