cleanup and add some new methods
This commit is contained in:
parent
222543645e
commit
ee38dbc1ad
83
src/lib.rs
83
src/lib.rs
|
@ -1,4 +1,4 @@
|
|||
#![allow(unknown_lints)] // `warn(rustdoc::all)` triggers this for weird nightly reasons
|
||||
#![allow(unknown_lints)] // `warn(rustdoc::all)` triggers this for some reason
|
||||
#![warn(rustdoc::all)]
|
||||
#![warn(clippy::all)]
|
||||
#![warn(clippy::pedantic)]
|
||||
|
@ -21,14 +21,17 @@ use std::{
|
|||
|
||||
/// A smaller [`Cow<'static, str>`](Cow).
|
||||
///
|
||||
/// This type can represent either an [`&'static str`](prim@str), or a [`String`], and fits within 3 words
|
||||
/// (the same size as `String`). It does this by storing a capacity of `0` when it is borrowed.
|
||||
/// However, this does mean that it is impossible to distinguish between borrowed and owned when
|
||||
/// `capacity == len == 0`, but in that case it really doesn't matter much anyway since an owned
|
||||
/// `String` with capacity equal to zero has not yet allocated.
|
||||
/// This type can represent either an [`&'static str`](prim@str), or a [`String`], and fits within
|
||||
/// 3 words (the same size as `String`). It does this by storing a capacity of `0` when it is
|
||||
/// borrowed. However, this does mean that it is impossible to distinguish between borrowed and
|
||||
/// owned when `capacity == len == 0`, but in that case it really doesn't matter much anyway since
|
||||
/// an owned `String` with capacity equal to zero has not yet allocated.
|
||||
///
|
||||
/// When doing non-mutating actions such as [`Deref::deref`], the string remains in whatever state it
|
||||
/// was in. When doing mutating actions such as [`DerefMut::deref_mut`], the string becomes owned.
|
||||
/// Note that this method of distinguishing a borrowed string from an owned string still allows
|
||||
/// storing a [`NonNull`] pointer, So this type is *still* 3 words when in an [`Option`].
|
||||
///
|
||||
/// When doing non-mutating actions such as [`Deref::deref`], the string remains in whatever state
|
||||
/// it was in. When doing mutating actions such as [`DerefMut::deref_mut`], the string is made owned.
|
||||
///
|
||||
/// ## Mutation as a `String`
|
||||
///
|
||||
|
@ -149,13 +152,9 @@ impl Stringish {
|
|||
/// If the `Stringish` is borrowed, the data is copied into a new allocation and the
|
||||
/// `Stringish` becomes owned. Otherwise, nothing happens.
|
||||
pub fn make_owned(&mut self) {
|
||||
if let None | Some(true) = self.is_owned() {
|
||||
return;
|
||||
if let Some(s) = self.as_static_str() {
|
||||
*self = Stringish::new_owned(String::from(s));
|
||||
}
|
||||
|
||||
let mut s = String::with_capacity(self.len);
|
||||
s.push_str(self);
|
||||
*self = Stringish::new_owned(s);
|
||||
}
|
||||
|
||||
/// Converts a `Stringish` into an owned [`String`].
|
||||
|
@ -171,7 +170,48 @@ impl Stringish {
|
|||
unsafe { String::from_raw_parts(this.ptr.as_ptr(), this.len, this.cap) }
|
||||
}
|
||||
|
||||
// Reborrowing
|
||||
/// Returns the inner [`&'static str`](prim@str) if the `Stringish` is borrowed.
|
||||
#[must_use]
|
||||
pub fn as_static_str(&self) -> Option<&'static str> {
|
||||
if let None | Some(true) = self.is_borrowed() {
|
||||
// SAFETY: if we are borrowed then we borrow a `&'static str`, so lifetime extension is safe
|
||||
Some(unsafe { &*(self.as_str() as *const str) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the `Stringish` into a [`Cow<'static, str>`](Cow).
|
||||
///
|
||||
/// This is the inverse of [`Stringish::from_cow`]
|
||||
#[must_use]
|
||||
pub fn into_cow(self) -> Cow<'static, str> {
|
||||
if let Some(s) = self.as_static_str() {
|
||||
Cow::Borrowed(s)
|
||||
} else {
|
||||
Cow::Owned(self.into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes and leaks the `Stringish`, returning an immutable reference to the contents.
|
||||
///
|
||||
/// If the `Stringish` is borrowed, no allocation needs to be created since it already contains
|
||||
/// a [`&'static str`](prim@str).
|
||||
///
|
||||
/// If you wish to get a mutable reference, see [`String::leak`].
|
||||
#[must_use]
|
||||
pub fn leak(self) -> &'static str {
|
||||
if let Some(s) = self.as_static_str() {
|
||||
s
|
||||
} else {
|
||||
// SAFETY: workaround for `String::leak` being unstable
|
||||
unsafe { str::from_utf8_unchecked(self.into_owned().into_bytes().leak()) }
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Reborrowing //
|
||||
/////////////////
|
||||
|
||||
/// Returns a byte slice of this `Stringish`'s contents.
|
||||
#[must_use]
|
||||
|
@ -239,6 +279,15 @@ impl From<Cow<'static, str>> for Stringish {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts a `Stringish` into a [`Cow<'static, str>`](Cow).
|
||||
///
|
||||
/// See also: [`Stringish::into_cow`]
|
||||
impl From<Stringish> for Cow<'static, str> {
|
||||
fn from(stringish: Stringish) -> Self {
|
||||
stringish.into_cow()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Stringish {
|
||||
type Target = str;
|
||||
|
||||
|
@ -254,7 +303,9 @@ impl DerefMut for Stringish {
|
|||
}
|
||||
|
||||
impl Stringish {
|
||||
// Mutation as a `String`
|
||||
////////////////////////////
|
||||
// Mutation as a `String` //
|
||||
////////////////////////////
|
||||
|
||||
/// Allows mutation of this `Stringish` as a `String` using a guard.
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue