# representation of `"hello"` is:
)]
use crate::array::{Array, ArrayCloner, ArrayLen};
use crate::newtype::define_varlen_newtype;
use crate::{impl_initializer_as_newtype, Initializer, VClone, VCopy};
use core::pin::Pin;
define_varlen_newtype! {
#[repr(transparent)]
#[doc = crate::doc_macro::make_svgbobdoc!(
/// A string with inline storage.
///
/// This consists of an integer `length` field, followed immediately by the utf8 string payload.
/// For example, the [`VBox<String>`](crate::VBox) representation of `"hello"` is:
)]
pub struct Str<(Len: ArrayLen = usize)>(Array<u8, Len>);
with signature: impl<(Len: ArrayLen)> Str<(Len)> { _ }
with init: struct StrInit<_>(_);
with inner_ref: fn inner(&self) -> &_;
with inner_mut: fn inner_mut(self: _) -> _;
}
impl<Len: ArrayLen> core::ops::Deref for Str<Len> {
type Target = str;
fn deref(&self) -> &Self::Target {
let slice: &[u8] = &self.inner();
unsafe {
core::str::from_utf8_unchecked(slice)
}
}
}
#[allow(rustdoc::missing_doc_code_examples)]
impl<Len: ArrayLen> Str<Len> {
pub fn mut_slice(self: Pin<&mut Self>) -> &mut str {
let slice = self.inner_mut().mut_slice();
unsafe {
core::str::from_utf8_unchecked_mut(slice)
}
}
}
#[allow(rustdoc::missing_doc_code_examples)]
impl Str {
pub fn copy(s: &str) -> impl Initializer<Self> + '_ {
Str::try_copy(s).unwrap()
}
}
#[allow(rustdoc::missing_doc_code_examples)]
impl<Len: ArrayLen> Str<Len> {
pub fn try_copy(s: &str) -> Option<impl Initializer<Self> + '_> {
Some(StrInit(Array::try_copy(s.as_bytes())?))
}
}
pub struct StrCloner<'a, Len: ArrayLen>(StrInit<ArrayCloner<'a, u8, Len>>);
impl_initializer_as_newtype! {
impl<('a), (Len: ArrayLen)> Initializer<Str<Len>> for StrCloner<'a, Len> { _ }
}
impl<'a, Len: ArrayLen> VClone<'a> for Str<Len> {
type Cloner = StrCloner<'a, Len>;
fn vclone(&'a self) -> Self::Cloner {
StrCloner(StrInit(self.0.vclone()))
}
}
unsafe impl<'a, Len: ArrayLen> VCopy<'a> for Str<Len> {}