hipstr 0.2.0

Another immutable string: zero-cost static, inline representation for small strings, reference counting, and owned (but shared) slicing
Documentation

hipstr

Rust Clippy Miri codecov Docs MIT OR Apache-2.0

Yet another string for Rust πŸ¦€

  • no copy literal wrapping via from_static (a const constructor)
  • no alloc small strings (23 bytes on 64-bit platform)
  • no copy owned slices
  • zero dependency

And bytes too!

⚑ Examples

use hipstr::HipStr;

let simple_greetings = HipStr::from_static("Hello world");
let _clone = simple_greetings.clone(); // no copy

let user = "John";
let greetings = HipStr::from(format!("Hello {}", user));
let _user = greetings.slice(6..): // no copy

✏️ Features

  • serde: provides serialization/deserialization support with serde crate
  • unstable: exposes internal Backend trait that may change at any moment

☣️ Safety of hipstr

This crate uses unsafe extensively. 🀷

It exploits the 1-bit alignment niche in pointers existing on most platforms (I think all Rustc supported platforms) to distinguish the inline representation from the other representations.

To make things safer, Rust is tested thoroughly on multiple platforms, normally and with Miri (the MIR interpreter).

πŸ§ͺ Testing

β˜” Coverage

This crate has near full line coverage:

cargo llvm-cov --all-features --html
# or
cargo tarpaulin --all-features --out html --engine llvm

Check out the current coverage on Codecov:

Coverage grid

πŸ–₯️ Cross-platform testing

You can easily run the test on various platforms with cross:

cross test --target mips-unknown-linux-gnu          # 32-bit BE
cross test --target mips64-unknown-linux-gnuabi64   # 64-bit BE
cross test --target i686-unknown-linux-gnu          # 32-bit LE
cross test --target x86_64-unknown-linux-gnu        # 64-bit LE

πŸ” Miri

This crate runs successfully with Miri:

MIRIFLAGS=-Zmiri-symbolic-alignment-check cargo +nightly miri test

for SEED in $(seq 0 10); do
  echo "Trying seed: $SEED"
  MIRIFLAGS="-Zmiri-seed=$SEED" cargo +nightly miri test || { echo "Failing seed: $SEED"; break; };
done

To check with different word size and endianness:

# Big endian, 64-bit
cargo +nightly miri test --target mips64-unknown-linux-gnuabi64
# Little endian, 32-bit
cargo +nightly miri test --target i686-unknown-linux-gnu

πŸ“¦ Similar crates

  • arcstr: no inline repr, heavy slice (with dedicated substring type) and custom Arc.
  • flexstr: no slice, very similar but use an Arc<str> instead of an Arc<String> (remove one level of indirection but use fat pointers).
  • imstr: no inline repr, otherwise very similar.
  • and many more.

In short, HipStr, one string type to rule them all…

How standards proliferate

πŸš€ TODOs

  • More copy on write API (like imstr)?

πŸ“– Author and licenses

For now, just me PoLazarus πŸ‘»
Help welcome! 🚨

MIT + Apache