|
|
@ -138,7 +138,7 @@ impl HeapString {
|
|
|
|
|
|
|
|
|
|
|
|
impl From<HeapString> for String
|
|
|
|
impl From<HeapString> for String
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(from: HeapString) -> Self
|
|
|
|
fn from(from: HeapString) -> Self
|
|
|
|
{
|
|
|
|
{
|
|
|
|
from.into_boxed_str().into()
|
|
|
|
from.into_boxed_str().into()
|
|
|
@ -148,13 +148,51 @@ impl From<HeapString> for String
|
|
|
|
|
|
|
|
|
|
|
|
impl From<String> for HeapString
|
|
|
|
impl From<String> for HeapString
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(from: String) -> Self
|
|
|
|
fn from(from: String) -> Self
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Self::new(from.into_boxed_str())
|
|
|
|
Self::new(from.into_boxed_str())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<Box<str>> for HeapString
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(from: Box<str>) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Self::new(from)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<HeapString> for Box<str>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(from: HeapString) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
from.into_boxed_str()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<HeapString> for Box<[u8]>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(from: HeapString) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
from.into_boxed_bytes()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> From<&'a str> for HeapString
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(from: &'a str) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Self::new(from.into())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl ops::Drop for HeapString
|
|
|
|
impl ops::Drop for HeapString
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -396,6 +434,69 @@ impl<const SIZE: usize> ops::Deref for SmallString<SIZE>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a, const SIZE: usize> From<&'a str> for SmallString<SIZE>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
|
|
fn from(string: &'a str) -> Self {
|
|
|
|
|
|
|
|
if string.len() <= SIZE {
|
|
|
|
|
|
|
|
match StackString::<SIZE>::try_from(string) {
|
|
|
|
|
|
|
|
Ok(ss) => return ss.into(),
|
|
|
|
|
|
|
|
_ => (),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Too large, shunt to heap
|
|
|
|
|
|
|
|
HeapString::from(string).into()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<const SIZE: usize> From<StackString<SIZE>> for SmallString<SIZE>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
|
|
fn from(from: StackString<SIZE>) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Self {
|
|
|
|
|
|
|
|
inner: SmallStringInner {
|
|
|
|
|
|
|
|
stack: ManuallyDrop::new(from),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<const SIZE: usize> From<HeapString> for SmallString<SIZE>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(from: HeapString) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Self {
|
|
|
|
|
|
|
|
inner: SmallStringInner {
|
|
|
|
|
|
|
|
heap: ManuallyDrop::new(from),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<const SIZE: usize> From<SmallString<SIZE>> for HeapString
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
|
|
fn from(mut from: SmallString<SIZE>) -> Self
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let h = if from.is_allocated() {
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
ManuallyDrop::take(&mut from.inner.heap)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
from.inner.stack.as_str()
|
|
|
|
|
|
|
|
}.into()
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
std::mem::forget(from);
|
|
|
|
|
|
|
|
h
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<const SIZE: usize> From<String> for SmallString<SIZE>
|
|
|
|
impl<const SIZE: usize> From<String> for SmallString<SIZE>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
@ -511,4 +612,39 @@ impl<const SIZE: usize> fmt::Write for SmallString<SIZE>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: SmallString: io::Write impls when extending functions have been written
|
|
|
|
const _:() = {
|
|
|
|
|
|
|
|
use std::io::{
|
|
|
|
|
|
|
|
self,
|
|
|
|
|
|
|
|
Write,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<const SIZE: usize> Write for SmallString<SIZE>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
|
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
|
|
|
|
|
|
|
let buf = std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
|
|
|
|
|
|
|
Ok(self.extend_from_str(buf).len())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
|
|
|
|
let buf = std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
|
|
|
|
|
|
|
(self.extend_from_str(buf).len() == buf.len())
|
|
|
|
|
|
|
|
.then(|| ()).ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "failed to write entire buffer"))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
|
|
|
mod tests
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
|
|
fn extending()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let mut ss: SmallString<40> = "Hello world".into();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|