arcstr: A better reference-counted string type.

Build Status codecov Docs Latest Version

This crate defines ArcStr, a reference counted string type. It's essentially trying to be a better Arc<str> or Arc<String>, at least for most use cases.

ArcStr intentionally gives up some of the features of Arc which are rarely-used for Arc<str> (Weak, Arc::make_mut, ...). And in exchange, it gets a number of features that are very useful, especially for strings. Notably robust support for cheap/zero-cost ArcStrs holding static data (for example, string literals).

(Aside from this, it's also a single pointer, which can be good for performance and FFI)

Eventually, my hope is to provide a couple utility types built on top of ArcStr too (see github issues), but for now, just ArcStr is implemented.

Feature overview

A quick tour of the distinguishing features. Note that it offers essentially the full set of functionality you'd expect in addition — these are just the unique selling points (well, the literal support is the main distinguishing feature at the moment):

```rust use arcstr::ArcStr; // Works in const: const AMAZING: ArcStr = arcstr::literal!("amazing constant"); assert_eq!(AMAZING, "amazing constant");

// arcstr::literal! input can come from include_str! too: const MYBESTFILES: ArcStr = arcstr::literal!(include_str!("my-best-files.txt")); `` Or, you can define the literals in normal expressions. Note that these literals are essentially ["Zero Cost"][zero-cost]. Specifically, below we not only don't allocate any heap memory to instantiatewow` or any of the clones, we also don't have to perform any atomic reads or writes when cloning, or dropping them (or during any other operations on them).

```rust let wow: ArcStr = arcstr::literal!("Wow!"); assert_eq!("Wow!", wow); // This line is probably not something you want to do regularly, // but as mentioned, causes no extra allocations, nor performs any // atomic loads, stores, rmws, etc. let wowzers = wow.clone().clone().clone().clone();

// At some point in the future, we can get a &'static str out of one // of the literal ArcStrs too. let staticstr: Option<&'static str> = ArcStr::asstatic(&wowzers); asserteq!(staticstr, Some("Wow!"));

// Note that this returns None for dynamically allocated ArcStr: let dynamicarc = ArcStr::from(format!("cool {}", 123)); asserteq!(ArcStr::asstatic(&dynamicarc), None); ```

Note that there's a better list of benefits in the ArcStr documentation which covers some of the reasons you might want to use it over other alternatives.

Usage

It's a normal rust crate, drop it in your Cargo.toml dep section. In the wildly unlikely case that you're here and don't kown how:

toml arcstr = { version = "...", features = ["any", "features", "you", "want"] }

The following cargo features are available. None are on by default currently.