[][src]Struct arcstr::Substr

#[repr(C)]pub struct Substr(_, _, _);

A low-cost string type representing a view into an ArcStr.

Conceptually this is (ArcStr, Range<usize>) with ergonomic helpers. In implementation, the only difference between it and that is that the index type is u32 unless the substr-usize-indices feature is enabled, which makes them use usize.

Examples

use arcstr::{ArcStr, Substr};
let parent = ArcStr::from("foo   bar");
// The main way to create a Substr is with `ArcStr::substr`.
let substr: Substr = parent.substr(3..);
assert_eq!(substr, "   bar");
// You can use `substr_using` to turn a function which is
// `&str => &str` into a function over `Substr => Substr`.
// See also `substr_from`, `try_substr_{from,using}`, and
// the functions with the same name on `ArcStr`.
let trimmed = substr.substr_using(str::trim);
assert_eq!(trimmed, "bar");

Caveats

The main caveat is the bit about index types. The index type is u32 by default. You can turn on substr-usize-indices if you desire though. The feature doesn't change the public API at all, just makes it able to handle enormous strings without panicking. This seems very niche to me, though.

Implementations

impl Substr[src]

pub const fn new() -> Self[src]

Construct an empty substr.

Examples

let s = Substr::new();
assert_eq!(s, "");

pub fn full(a: ArcStr) -> Self[src]

Construct a Substr over the entire ArcStr.

This is also provided as Substr::from(some_arcstr), and can be accomplished with a.substr(..), a.into_substr(..), ...

Examples

let s = Substr::full(ArcStr::from("foo"));
assert_eq!(s, "foo");
assert_eq!(s.range(), 0..3);

pub fn substr(&self, range: impl RangeBounds<usize>) -> Self[src]

Extract a substr of this substr.

If the result would be empty, a new strong reference to our parent is not created.

Examples

let s: Substr = arcstr::literal!("foobarbaz").substr(3..);
assert_eq!(s.as_str(), "barbaz");

let s2 = s.substr(1..5);
assert_eq!(s2, "arba");

Panics

If any of the following are untrue, we panic

  • range.start() <= range.end()
  • range.end() <= self.len()
  • self.is_char_boundary(start) && self.is_char_boundary(end)
  • These can be conveniently verified in advance using self.get(start..end).is_some() if needed.

pub fn as_str(&self) -> &str[src]

Extract a string slice containing our data.

Note: This is an equivalent to our Deref implementation, but can be more readable than &*s in the cases where a manual invocation of Deref would be required.

Examples

let s: Substr = arcstr::literal!("foobar").substr(3..);
assert_eq!(s.as_str(), "bar");

pub fn len(&self) -> usize[src]

Returns the length of this Substr in bytes.

Examples

let a: Substr = ArcStr::from("foo").substr(1..);
assert_eq!(a.len(), 2);

pub fn is_empty(&self) -> bool[src]

Returns true if this Substr is empty.

Examples

assert!(arcstr::literal!("abc").substr(3..).is_empty());
assert!(!arcstr::literal!("abc").substr(2..).is_empty());
assert!(Substr::new().is_empty());

pub fn to_string(&self) -> String[src]

Convert us to a std::string::String.

This is provided as an inherent method to avoid needing to route through the Display machinery, but is equivalent to ToString::to_string.

Examples

let s: Substr = arcstr::literal!("12345").substr(1..4);
assert_eq!(s.to_string(), "234");

pub const unsafe fn from_parts_unchecked(s: ArcStr, range: Range<usize>) -> Self[src]

Unchecked function to cunstruct a Substr from an ArcStr and a byte range. Direct usage of this function is largely discouraged in favor of ArcStr::substr, or the literal_substr! macro, which currently is implemented using a call to this function (however, can guarantee safe usage).

This is unsafe because currently ArcStr cannot provide a &str in a const fn. If that changes then we will likely deprecate this function, and provide a pub const fn from_parts with equivalent functionality.

In the distant future, it would be nice if this accepted other kinds of ranges too.

Examples

use arcstr::{ArcStr, Substr};
const FOOBAR: ArcStr = arcstr::literal!("foobar");
const OBA: Substr = unsafe { Substr::from_parts_unchecked(FOOBAR, 2..5) };
assert_eq!(OBA, "oba");

Safety

You promise that range is in bounds for s, and that the start and end are both on character boundaries. Note that we do check that the usize indices fit into u32 if thats our configured index type, so _unchecked is not entirely a lie.

Panics

If the substr-usize-indices is not enabled, and the target arch is 64-bit, and the usizes do not fit in 32 bits, then we panic with a (possibly strange-looking) index-out-of-bounds error in order to force compilation failure.

pub fn shallow_eq(this: &Self, o: &Self) -> bool[src]

Returns true if the two Substrs have identical parents, and are covering the same range.

Note that the "identical"ness of parents is determined by ArcStr::ptr_eq, which can have surprising/nondeterministic results when used on const ArcStrs. It is guaranteed that Substr::clone()s will be shallow_eq eachother, however.

This should generally only be used as an optimization, or a debugging aide. Additionally, it is already used in the implementation of PartialEq, so optimizing a comparison by performing it first is generally unnecessary.

Examples

let parent = ArcStr::from("foooo");
let sub1 = parent.substr(1..3);
let sub2 = parent.substr(1..3);
assert!(Substr::shallow_eq(&sub1, &sub2));
// Same parent *and* contents, but over a different range: not `shallow_eq`.
let not_same = parent.substr(3..);
assert!(!Substr::shallow_eq(&sub1, &not_same));

pub fn parent(&self) -> &ArcStr[src]

Returns the ArcStr this is a substring of.

Note that the exact pointer value of this can be somewhat nondeterministic when used with const ArcStrs. For example

This example is not tested
const FOO: ArcStr = arcstr::literal!("foo");
// This is non-deterministic, as all references to a given
// const are not required to point to the same value.
ArcStr::ptr_eq(FOO.substr(..).parent(), &FOO);

Examples

let parent = ArcStr::from("abc def");
let child = parent.substr(2..5);
assert!(ArcStr::ptr_eq(&parent, child.parent()));

let child = parent.substr(..);
assert_eq!(child.range(), 0..7);

pub fn range(&self) -> Range<usize>[src]

Returns the range of bytes we occupy inside our parent.

This range is always guaranteed to:

  • Have an end >= start.
  • Have both start and end be less than or equal to self.parent().len()
  • Have both start and end be on meet self.parent().is_char_boundary(b)

To put another way, it's always sound to do s.parent().get_unchecked(s.range()).

let parent = ArcStr::from("abc def");
let child = parent.substr(2..5);
assert_eq!(child.range(), 2..5);

let child = parent.substr(..);
assert_eq!(child.range(), 0..7);

pub fn substr_from(&self, substr: &str) -> Substr[src]

Returns a Substr of self over the given &str, or panics.

It is not rare to end up with a &str which holds a view into a Substr's backing data. A common case is when using functionality that takes and returns &str and are entirely unaware of arcstr, for example: str::trim().

This function allows you to reconstruct a Substr from a &str which is a view into this Substr's backing string.

See Substr::try_substr_from for a version that returns an option rather than panicking.

Examples

use arcstr::Substr;
let text = Substr::from("   abc");
let trimmed = text.trim();
let substr: Substr = text.substr_from(trimmed);
assert_eq!(substr, "abc");

Panics

Panics if substr isn't a view into our memory.

Also panics if substr is a view into our memory but is >= u32::MAX bytes away from our start, if we're a 64-bit machine and substr-usize-indices is not enabled.

pub fn try_substr_from(&self, substr: &str) -> Option<Substr>[src]

If possible, returns a Substr of self over the given &str.

This is a fallible version of Substr::substr_from.

It is not rare to end up with a &str which holds a view into a ArcStr's backing data. A common case is when using functionality that takes and returns &str and are entirely unaware of arcstr, for example: str::trim().

This function allows you to reconstruct a Substr from a &str which is a view into this Substr's backing string. Note that we accept the empty string as input, in which case we return the same value as Substr::new (For clarity, this no longer holds a reference to self.parent()).

Examples

use arcstr::Substr;
let text = Substr::from("   abc");
let trimmed = text.trim();
let substr: Option<Substr> = text.try_substr_from(trimmed);
assert_eq!(substr.unwrap(), "abc");
// `&str`s not derived from `self` will return None.
let not_substr = text.try_substr_from("abc");
assert!(not_substr.is_none());

Panics

Panics if substr is a view into our memory but is >= u32::MAX bytes away from our start, on a 64-bit machine, when substr-usize-indices is not enabled.

pub fn try_substr_using(&self, f: impl FnOnce(&str) -> &str) -> Option<Self>[src]

Compute a derived &str a function of &str => &str, and produce a Substr of the result if possible.

The function may return either a derived string, or any empty string.

This function is mainly a wrapper around Substr::try_substr_from. If you're coming to arcstr from the shared_string crate, this is the moral equivalent of the slice_with function.

Examples

use arcstr::Substr;
let text = Substr::from("   abc");
let trimmed: Option<Substr> = text.try_substr_using(str::trim);
assert_eq!(trimmed.unwrap(), "abc");
let other = text.try_substr_using(|_s| "different string!");
assert_eq!(other, None);
// As a special case, this is allowed.
let empty = text.try_substr_using(|_s| "");
assert_eq!(empty.unwrap(), "");

pub fn substr_using(&self, f: impl FnOnce(&str) -> &str) -> Self[src]

Compute a derived &str a function of &str => &str, and produce a Substr of the result.

The function may return either a derived string, or any empty string. Returning anything else will result in a panic.

This function is mainly a wrapper around Substr::try_substr_from. If you're coming to arcstr from the shared_string crate, this is the likely closest to the slice_with_unchecked function, but this panics instead of UB on dodginess.

Examples

use arcstr::Substr;
let text = Substr::from("   abc");
let trimmed: Substr = text.substr_using(str::trim);
assert_eq!(trimmed, "abc");
// As a special case, this is allowed.
let empty = text.substr_using(|_s| "");
assert_eq!(empty, "");

Trait Implementations

impl AsRef<[u8]> for Substr[src]

impl AsRef<str> for Substr[src]

impl Borrow<str> for Substr[src]

impl Clone for Substr[src]

impl Debug for Substr[src]

impl Default for Substr[src]

impl Deref for Substr[src]

type Target = str

The resulting type after dereferencing.

impl Display for Substr[src]

impl Eq for Substr[src]

impl<'_> From<&'_ ArcStr> for Substr[src]

impl<'_> From<&'_ String> for Substr[src]

impl<'_> From<&'_ mut str> for Substr[src]

impl<'_> From<&'_ str> for Substr[src]

impl<'a> From<&'a Substr> for Cow<'a, str>[src]

impl From<Arc<str>> for Substr[src]

impl From<ArcStr> for Substr[src]

impl From<Box<str>> for Substr[src]

impl<'_> From<Cow<'_, str>> for Substr[src]

impl From<Rc<str>> for Substr[src]

impl From<String> for Substr[src]

impl<'a> From<Substr> for Cow<'a, str>[src]

impl FromStr for Substr[src]

type Err = Infallible

The associated error which can be returned from parsing.

impl Hash for Substr[src]

impl Index<Range<usize>> for Substr[src]

type Output = str

The returned type after indexing.

impl Index<RangeFrom<usize>> for Substr[src]

type Output = str

The returned type after indexing.

impl Index<RangeFull> for Substr[src]

type Output = str

The returned type after indexing.

impl Index<RangeInclusive<usize>> for Substr[src]

type Output = str

The returned type after indexing.

impl Index<RangeTo<usize>> for Substr[src]

type Output = str

The returned type after indexing.

impl Index<RangeToInclusive<usize>> for Substr[src]

type Output = str

The returned type after indexing.

impl Ord for Substr[src]

impl<'a> PartialEq<&'a str> for Substr[src]

impl<'a> PartialEq<Arc<str>> for Substr[src]

impl PartialEq<ArcStr> for Substr[src]

impl<'a> PartialEq<Box<str>> for Substr[src]

impl<'a> PartialEq<Cow<'a, str>> for Substr[src]

impl<'a> PartialEq<Rc<str>> for Substr[src]

impl<'a> PartialEq<String> for Substr[src]

impl PartialEq<Substr> for Substr[src]

impl PartialEq<Substr> for ArcStr[src]

impl<'a> PartialEq<Substr> for str[src]

impl<'a> PartialEq<Substr> for &'a str[src]

impl<'a> PartialEq<Substr> for String[src]

impl<'a> PartialEq<Substr> for Cow<'a, str>[src]

impl<'a> PartialEq<Substr> for Box<str>[src]

impl<'a> PartialEq<Substr> for Arc<str>[src]

impl<'a> PartialEq<Substr> for Rc<str>[src]

impl<'a> PartialEq<str> for Substr[src]

impl PartialOrd<Substr> for Substr[src]

Auto Trait Implementations

impl RefUnwindSafe for Substr

impl Send for Substr

impl Sync for Substr

impl Unpin for Substr

impl UnwindSafe for Substr

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.