Rename StackString to InlineString to reflect the fact that it may not always be on the stack, rename modules

main
Pantonshire 3 years ago
parent da09d5015b
commit 74e2bbf406

@ -9,12 +9,12 @@ use std::{
}; };
#[derive(Clone)] #[derive(Clone)]
pub struct StackString<const N: usize> { pub struct InlineString<const N: usize> {
buf: [u8; N], buf: [u8; N],
len: u8, len: u8,
} }
impl<const N: usize> StackString<N> { impl<const N: usize> InlineString<N> {
const MAX_LEN: u8 = { const MAX_LEN: u8 = {
#[allow(clippy::cast_possible_truncation, clippy::checked_conversions)] #[allow(clippy::cast_possible_truncation, clippy::checked_conversions)]
if N <= u8::MAX as usize { if N <= u8::MAX as usize {
@ -24,7 +24,7 @@ impl<const N: usize> StackString<N> {
} }
}; };
/// Creates a new `StackString` from a given byte buffer and length. /// Creates a new `InlineString` from a given byte buffer and length.
/// ///
/// # Safety /// # Safety
/// ///
@ -35,7 +35,7 @@ impl<const N: usize> StackString<N> {
Self { buf, len } Self { buf, len }
} }
/// Returns a new empty `StackString`. /// Returns a new empty `InlineString`.
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn empty() -> Self { pub const fn empty() -> Self {
@ -46,7 +46,7 @@ impl<const N: usize> StackString<N> {
} }
#[inline] #[inline]
pub fn new<S>(s: &S) -> Result<Self, StackStringError> pub fn new<S>(s: &S) -> Result<Self, InlineStringError>
where where
S: AsRef<str> + ?Sized, S: AsRef<str> + ?Sized,
{ {
@ -55,11 +55,11 @@ impl<const N: usize> StackString<N> {
let s = <S as AsRef<str>>::as_ref(s).as_bytes(); let s = <S as AsRef<str>>::as_ref(s).as_bytes();
// If the length of the string is greater than `Self::MAX_LEN`, it will not fit in the // If the length of the string is greater than `Self::MAX_LEN`, it will not fit in the
// stack buffer so return `None`. // buffer so return `None`.
let len = u8::try_from(s.len()) let len = u8::try_from(s.len())
.ok() .ok()
.and_then(|len| (len <= Self::MAX_LEN).then_some(len)) .and_then(|len| (len <= Self::MAX_LEN).then_some(len))
.ok_or(StackStringError { .ok_or(InlineStringError {
max_len: N, max_len: N,
actual_len: s.len(), actual_len: s.len(),
})?; })?;
@ -76,24 +76,24 @@ impl<const N: usize> StackString<N> {
/// Returns a string slice pointing to the underlying string data. /// Returns a string slice pointing to the underlying string data.
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
// SAFETY: // SAFETY:
// `len` being less than or equal to `N` is an invariant of `StackString`, so it is // `len` being less than or equal to `N` is an invariant of `InlineString`, so it is
// always within the bounds of `buf`. // always within the bounds of `buf`.
let slice = unsafe { self.buf.get_unchecked(..usize::from(self.len)) }; let slice = unsafe { self.buf.get_unchecked(..usize::from(self.len)) };
// SAFETY: // SAFETY:
// The first `len` bytes of `buf` being valid UTF-8 is an invariant of `StackString`. // The first `len` bytes of `buf` being valid UTF-8 is an invariant of `InlineString`.
unsafe { str::from_utf8_unchecked(slice) } unsafe { str::from_utf8_unchecked(slice) }
} }
/// Returns a mutable string slice pointing to the underlying string data. /// Returns a mutable string slice pointing to the underlying string data.
pub fn as_str_mut(&mut self) -> &mut str { pub fn as_str_mut(&mut self) -> &mut str {
// SAFETY: // SAFETY:
// `len` being less than or equal to `N` is an invariant of `StackString`, so it is // `len` being less than or equal to `N` is an invariant of `InlineString`, so it is
// always within the bounds of `buf`. // always within the bounds of `buf`.
let slice = unsafe { self.buf.get_unchecked_mut(..usize::from(self.len)) }; let slice = unsafe { self.buf.get_unchecked_mut(..usize::from(self.len)) };
// SAFETY: // SAFETY:
// The first `len` bytes of `buf` being valid UTF-8 is an invariant of `StackString`. // The first `len` bytes of `buf` being valid UTF-8 is an invariant of `InlineString`.
unsafe { str::from_utf8_unchecked_mut(slice) } unsafe { str::from_utf8_unchecked_mut(slice) }
} }
@ -110,14 +110,14 @@ impl<const N: usize> StackString<N> {
} }
} }
impl<const N: usize> Default for StackString<N> { impl<const N: usize> Default for InlineString<N> {
#[inline] #[inline]
fn default() -> Self { fn default() -> Self {
Self::empty() Self::empty()
} }
} }
impl<const N: usize> ops::Deref for StackString<N> { impl<const N: usize> ops::Deref for InlineString<N> {
type Target = str; type Target = str;
#[inline] #[inline]
@ -126,43 +126,43 @@ impl<const N: usize> ops::Deref for StackString<N> {
} }
} }
impl<const N: usize> ops::DerefMut for StackString<N> { impl<const N: usize> ops::DerefMut for InlineString<N> {
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.as_str_mut() self.as_str_mut()
} }
} }
impl<const N: usize> AsRef<str> for StackString<N> { impl<const N: usize> AsRef<str> for InlineString<N> {
#[inline] #[inline]
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
self self
} }
} }
impl<const N: usize> AsMut<str> for StackString<N> { impl<const N: usize> AsMut<str> for InlineString<N> {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut str { fn as_mut(&mut self) -> &mut str {
self self
} }
} }
impl<const N: usize> borrow::Borrow<str> for StackString<N> { impl<const N: usize> borrow::Borrow<str> for InlineString<N> {
#[inline] #[inline]
fn borrow(&self) -> &str { fn borrow(&self) -> &str {
self self
} }
} }
impl<const N: usize> borrow::BorrowMut<str> for StackString<N> { impl<const N: usize> borrow::BorrowMut<str> for InlineString<N> {
#[inline] #[inline]
fn borrow_mut(&mut self) -> &mut str { fn borrow_mut(&mut self) -> &mut str {
self self
} }
} }
impl<'a, const N: usize> TryFrom<&'a str> for StackString<N> { impl<'a, const N: usize> TryFrom<&'a str> for InlineString<N> {
type Error = StackStringError; type Error = InlineStringError;
#[inline] #[inline]
fn try_from(s: &'a str) -> Result<Self, Self::Error> { fn try_from(s: &'a str) -> Result<Self, Self::Error> {
@ -170,8 +170,8 @@ impl<'a, const N: usize> TryFrom<&'a str> for StackString<N> {
} }
} }
impl<const N: usize> TryFrom<String> for StackString<N> { impl<const N: usize> TryFrom<String> for InlineString<N> {
type Error = StackStringError; type Error = InlineStringError;
#[inline] #[inline]
fn try_from(s: String) -> Result<Self, Self::Error> { fn try_from(s: String) -> Result<Self, Self::Error> {
@ -179,8 +179,8 @@ impl<const N: usize> TryFrom<String> for StackString<N> {
} }
} }
impl<'a, const N: usize> TryFrom<Cow<'a, str>> for StackString<N> { impl<'a, const N: usize> TryFrom<Cow<'a, str>> for InlineString<N> {
type Error = StackStringError; type Error = InlineStringError;
#[inline] #[inline]
fn try_from(s: Cow<'a, str>) -> Result<Self, Self::Error> { fn try_from(s: Cow<'a, str>) -> Result<Self, Self::Error> {
@ -188,45 +188,45 @@ impl<'a, const N: usize> TryFrom<Cow<'a, str>> for StackString<N> {
} }
} }
impl<const N: usize> From<StackString<N>> for String { impl<const N: usize> From<InlineString<N>> for String {
#[inline] #[inline]
fn from(s: StackString<N>) -> Self { fn from(s: InlineString<N>) -> Self {
s.into_string() s.into_string()
} }
} }
impl<const N: usize, const M: usize> PartialEq<StackString<M>> for StackString<N> { impl<const N: usize, const M: usize> PartialEq<InlineString<M>> for InlineString<N> {
#[inline] #[inline]
fn eq(&self, other: &StackString<M>) -> bool { fn eq(&self, other: &InlineString<M>) -> bool {
**self == **other **self == **other
} }
} }
impl<const N: usize> Eq for StackString<N> {} impl<const N: usize> Eq for InlineString<N> {}
impl<const N: usize, const M: usize> PartialOrd<StackString<M>> for StackString<N> { impl<const N: usize, const M: usize> PartialOrd<InlineString<M>> for InlineString<N> {
#[inline] #[inline]
fn partial_cmp(&self, other: &StackString<M>) -> Option<Ordering> { fn partial_cmp(&self, other: &InlineString<M>) -> Option<Ordering> {
(**self).partial_cmp(&**other) (**self).partial_cmp(&**other)
} }
} }
impl<const N: usize> Ord for StackString<N> { impl<const N: usize> Ord for InlineString<N> {
#[inline] #[inline]
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
(**self).cmp(&**other) (**self).cmp(&**other)
} }
} }
impl<const N: usize> Hash for StackString<N> { impl<const N: usize> Hash for InlineString<N> {
#[inline] #[inline]
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state); (**self).hash(state);
} }
} }
impl<const N: usize> str::FromStr for StackString<N> { impl<const N: usize> str::FromStr for InlineString<N> {
type Err = StackStringError; type Err = InlineStringError;
#[inline] #[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -234,14 +234,14 @@ impl<const N: usize> str::FromStr for StackString<N> {
} }
} }
impl<const N: usize> fmt::Debug for StackString<N> { impl<const N: usize> fmt::Debug for InlineString<N> {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f) fmt::Debug::fmt(&**self, f)
} }
} }
impl<const N: usize> fmt::Display for StackString<N> { impl<const N: usize> fmt::Display for InlineString<N> {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f) fmt::Display::fmt(&**self, f)
@ -249,12 +249,12 @@ impl<const N: usize> fmt::Display for StackString<N> {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct StackStringError { pub struct InlineStringError {
max_len: usize, max_len: usize,
actual_len: usize, actual_len: usize,
} }
impl StackStringError { impl InlineStringError {
pub fn max_len(&self) -> usize { pub fn max_len(&self) -> usize {
self.max_len self.max_len
} }
@ -264,15 +264,15 @@ impl StackStringError {
} }
} }
impl fmt::Display for StackStringError { impl fmt::Display for InlineStringError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"string of length {} exceeds limit for `StackString<{}>`", "string of length {} exceeds limit for `InlineString<{}>`",
self.actual_len, self.actual_len,
self.max_len self.max_len
) )
} }
} }
impl error::Error for StackStringError {} impl error::Error for InlineStringError {}

@ -1,8 +1,8 @@
pub mod experimental; pub mod experimental;
pub mod fixed_string; pub mod fixed;
pub mod stack_string; pub mod inline;
pub mod shstring; pub mod shstring;
pub use fixed_string::{FixedString, Error as FixedStringError}; pub use fixed::{FixedString, Error as FixedStringError};
pub use stack_string::StackString; pub use inline::InlineString;
pub use shstring::{ShString, ShString22}; pub use shstring::{ShString, ShString22};

@ -8,7 +8,7 @@ use std::{
str::FromStr, str::FromStr,
}; };
use super::StackString; use super::InlineString;
/// A non-growable string where strings 22 bytes or shorter are stored on the stack and longer /// A non-growable string where strings 22 bytes or shorter are stored on the stack and longer
/// strings are stored on the heap. /// strings are stored on the heap.
@ -35,7 +35,7 @@ impl<const N: usize> ShString<N> {
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn empty() -> Self { pub const fn empty() -> Self {
Self(Repr::Stack(StackString::empty())) Self(Repr::Inline(InlineString::empty()))
} }
/// Creates a new `ShString` from the given string slice, putting it on the stack if possible /// Creates a new `ShString` from the given string slice, putting it on the stack if possible
@ -47,8 +47,8 @@ impl<const N: usize> ShString<N> {
S: AsRef<str>, S: AsRef<str>,
Box<str>: From<S>, Box<str>: From<S>,
{ {
match StackString::new(&s) { match InlineString::new(&s) {
Ok(stack_buf) => Self(Repr::Stack(stack_buf)), Ok(stack_buf) => Self(Repr::Inline(stack_buf)),
Err(_) => Self(Repr::Heap(Box::<str>::from(s))), Err(_) => Self(Repr::Heap(Box::<str>::from(s))),
} }
} }
@ -58,7 +58,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
match self { match self {
Self(Repr::Stack(buf)) => buf, Self(Repr::Inline(buf)) => buf,
Self(Repr::Heap(buf)) => buf, Self(Repr::Heap(buf)) => buf,
} }
} }
@ -68,7 +68,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn as_str_mut(&mut self) -> &mut str { pub fn as_str_mut(&mut self) -> &mut str {
match self { match self {
Self(Repr::Stack(buf)) => buf, Self(Repr::Inline(buf)) => buf,
Self(Repr::Heap(buf)) => buf, Self(Repr::Heap(buf)) => buf,
} }
} }
@ -78,7 +78,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn into_string(self) -> String { pub fn into_string(self) -> String {
match self { match self {
Self(Repr::Stack(buf)) => buf.into_string(), Self(Repr::Inline(buf)) => buf.into_string(),
Self(Repr::Heap(buf)) => buf.into_string(), Self(Repr::Heap(buf)) => buf.into_string(),
} }
} }
@ -94,7 +94,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
match self { match self {
Self(Repr::Stack(buf)) => buf.len(), Self(Repr::Inline(buf)) => buf.len(),
Self(Repr::Heap(buf)) => buf.len(), Self(Repr::Heap(buf)) => buf.len(),
} }
} }
@ -113,7 +113,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
match self { match self {
Self(Repr::Stack(buf)) => buf.is_empty(), Self(Repr::Inline(buf)) => buf.is_empty(),
Self(Repr::Heap(buf)) => buf.is_empty(), Self(Repr::Heap(buf)) => buf.is_empty(),
} }
} }
@ -132,7 +132,7 @@ impl<const N: usize> ShString<N> {
#[must_use] #[must_use]
pub fn heap_allocated(&self) -> bool { pub fn heap_allocated(&self) -> bool {
match self { match self {
Self(Repr::Stack(_)) => false, Self(Repr::Inline(_)) => false,
Self(Repr::Heap(_)) => true, Self(Repr::Heap(_)) => true,
} }
} }
@ -293,7 +293,7 @@ impl<'de, const N: usize> serde::Deserialize<'de> for ShString<N> {
#[derive(Clone)] #[derive(Clone)]
enum Repr<const N: usize> { enum Repr<const N: usize> {
Stack(StackString<N>), Inline(InlineString<N>),
Heap(Box<str>), Heap(Box<str>),
} }

Loading…
Cancel
Save