Immutable strings, in Rust.

Overview

Immutable Strings

crates.io

Inspired by the bytes crate, which offers zero-copy byte slices, this crate does the same but for strings. It is backed by standard library string that is stored by smart pointer, and every instance contains a range into that String. This allows for cheap zero-copy cloning and slicing of the string. This is especially useful for parsing operations, where a large string needs to be sliced into a lot of substrings.

TL;DR: This crate offers an ImString type that acts as a String (in that it can be modified and used in the same way), an Arc<String> (in that it is cheap to clone) and an &str (in that it is cheap to slice) all in one, owned type.

Diagram of ImString Internals

This crate offers a safe API that ensures that every string and every string slice is UTF-8 encoded. It does not allow slicing of strings within UTF-8 multibyte sequences. It offers try_* functions for every operation that can fail to avoid panics. It also uses extensive unit testing with a full test coverage to ensure that there is no unsoundness.

Features

Efficient Cloning: The crate's architecture enables low-cost (zero-copy) clone and slice creation, making it ideal for parsing strings that are widely shared.

Efficient Slicing: The crate's architecture enables low-cost (zero-copy) slice creation, making it ideal for parsing operations where one large input string is slices into many smaller strings.

Copy on Write: Despite being cheap to clone and slice, it allows for mutation using copy-on-write. For strings that are not shared, it has an optimisation to be able to mutate it in-place safely to avoid unnecessary copying.

Compatibility: The API is designed to closely resemble Rust's standard library String, facilitating smooth integration and being almost a drop-in replacement.

Generic over Storage: The crate is flexible in terms of how the data is stored. It allows for using Arc<String> for multithreaded applications and Rc<String> for single-threaded use, providing adaptability to different storage requirements and avoiding the need to pay for atomic operations when they are not needed.

Safety: The crate enforces that all strings and string slices are UTF-8 encoded. Any methods that might violate this are marked as unsafe. All methods that can fail have a try_* variant that will not panic. Use of safe functions cannot result in unsound behaviour.

Example

use imstr::ImString;

// Create new ImString, allocates data.
let mut string = ImString::from("Hello, World");

// Edit: happens in-place (because this is the only reference).
string.push_str("!");

// Clone: this is zero-copy.
let clone = string.clone();

// Slice: this is zero-copy.
let hello = string.slice(0..5);
assert_eq!(hello, "Hello");

// Slice: this is zero-copy.
let world = string.slice(7..12);
assert_eq!(world, "World");

// Here we have to copy only the part that the slice refers to so it can be modified.
let hello = hello + "!";
assert_eq!(hello, "Hello!");

Similar

This is a comparison of this crate to other, similar crates. The comparison is made on these features:

  • Cheap Clone: is it a zero-copy operation to clone a string?
  • Cheap Slice πŸ• : is it possibly to cheaply slice a string?
  • Mutable: is it possible to modify strings?
  • Generic Storage: is it possible to swap out the storage mechanism?
  • String Compatible: is it compatible with String?

Here is the data, with links to the crates for further examination:

Crate Cheap Clone Cheap Slice Mutable Generic Storage String Compatible Notes
imstr βœ… βœ… βœ… βœ… βœ… This crate.
tendril βœ… βœ… βœ… βœ… ❌ Complex implementation. API not quite compatible with String, but otherwise closest to what this crate does.
immut_string βœ… ❌ 🟑 (no optimization) ❌ ❌ Simply a wrapper around Arc<String>.
immutable_string βœ… ❌ ❌ ❌ ❌ Wrapper around Arc<str>.
arccstr βœ… ❌ ❌ ❌ ❌ Not UTF-8 (Null-terminated C string). Hand-written Arc implementation.
implicit-clone βœ… ❌ ❌ 🟑 βœ… Immutable string library. Has sync and unsync variants.
semistr ❌ ❌ ❌ ❌ ❌ Stores short strings inline.
quetta βœ… βœ… ❌ ❌ ❌ Wrapper around Arc<String> that can be sliced.
bytesstr βœ… 🟑 ❌ ❌ ❌ Wrapper around Bytes. Cannot be directly sliced.
fast-str βœ… ❌ ❌ ❌ ❌ Looks like there could be some unsafety.
flexstr βœ… ❌ ❌ βœ… ❌
bytestring βœ… 🟑 ❌ ❌ ❌ Wrapper around Bytes. Used by actix. Can be indirectly sliced using slice_ref().
arcstr βœ… βœ… ❌ ❌ ❌ Can store string literal as &'static str.
cowstr βœ… ❌ βœ… ❌ ❌ Reimplements Arc, custom allocation strategy.
strck ❌ ❌ ❌ βœ… ❌ Typechecked string library.

License

MIT, see LICENSE.md.

You might also like...
Rust-battery - Rust crate providing cross-platform information about the notebook batteries.

battery Rust crate providing cross-platform information about the notebook batteries. Table of contents Overview Supported platforms Install Examples

A Rust-based shell script to create a folder structure to use for a single class every semester. Mostly an excuse to use Rust.

A Rust Course Folder Shell Script PROJECT IN PROGRESS (Spring 2022) When completed, script will create a folder structure of the following schema: [ro

Rust Imaging Library's Python binding: A performant and high-level image processing library for Python written in Rust

ril-py Rust Imaging Library for Python: Python bindings for ril, a performant and high-level image processing library written in Rust. What's this? Th

FTL Rust Demangler is a command-line tool for demangling symbol names that are mangled with the Rust convention

FTL Rust Demangler is a command-line tool for demangling symbol names that are mangled with the Rust convention. It takes a mangled symbol name as input and returns the demangled name

rpm (Rust project manager) is a tool that helps you to manage your rust projects

rpm rpm (Rust project manager) is a open source tool for managing your rust project in an organized way Installation # make sure you have rust install

auto-rust is an experimental project that aims to automatically generate Rust code with LLM (Large Language Models) during compilation, utilizing procedural macros.
auto-rust is an experimental project that aims to automatically generate Rust code with LLM (Large Language Models) during compilation, utilizing procedural macros.

Auto Rust auto-rust is an experimental project that aims to automatically generate Rust code with LLM (Large Language Models) during compilation, util

Rusty Shellcode Reflective DLL Injection (sRDI) - A small reflective loader in Rust 4KB in size for generating position-independent code (PIC) in Rust.
Rusty Shellcode Reflective DLL Injection (sRDI) - A small reflective loader in Rust 4KB in size for generating position-independent code (PIC) in Rust.

Shellcode Reflective DLL Injection (sRDI) Shellcode reflective DLL injection (sRDI) is a process injection technique that allows us to convert a given

This rust compiler backend emmits valid CLR IR, enambling you to use Rust in .NET projects

What is rustc_codegen_clr? NOTE: this project is a very early proof-of-concept This is a compiler backend for rustc which targets the .NET platform an

RustGPT is a ChatGPT UI built with Rust + HTMX: the power of Rust coupled with the simplicity of HTMX πŸ’š

RustGPT πŸ¦€βœ¨ RustGPT.Blog.Post.mp4 Welcome to the RustGPT repository! Here, you'll find a web ChatGPT clone entirely crafted using Rust and HTMX, where

Releases(v0.1.0)
Owner
Patrick Elsen
I love coding, electronics, and explosions.
Patrick Elsen
Vari (VΓ€ri) is a Rust library for formatting strings with colors and cosmetic stuff to the terminal.

Vari Vari (VΓ€ri) is a Rust library for formatting strings with colors and cosmetic stuff to the terminal. Like Rich library for Python. VΓ€ri means "co

azur 13 Nov 2, 2022
Easy access of struct fields in strings using different/custom pre/postfix: "Hello, {field}" in rust

Easy access to struct fields in strings ?? add strung to the dependencies in the Cargo.toml: [dependencies] strung = "0.1.3" ?? use/import everything

Dekirisu 2 Sep 19, 2022
Rust parser/validator for Debian version strings

debian version handling in rust This simple crate provides a struct for parsing, validating, manipulating and comparing Debian version strings. It aim

Jelmer VernooΔ³ 2 Jul 8, 2023
Statically verified Rust struct field names as strings.

field Statically verified struct field names as strings. See the documentation for more details. Installation Add the following to your Cargo manifest

Indraneel Mahendrakumar 3 Jul 9, 2023
Small CLI for escaping and unescaping characters in strings

?? esc Small CLI for escaping characters in strings. Install cargo install esc Usage cat LICENSE-MIT | esc escape | pbcopy pbpaste | esc unescape | pb

Seth 1 Nov 26, 2021
Vim plugin to quickly parse strings into arrays.

butcher Vim plugin to quickly parse strings into arrays. It is painful to write arrays in any programming language, so butcher makes it easy for you.

null 5 Dec 31, 2021
A CLI tool to rename files to randomly generated strings.

rng-rename A CLI tool to rename files to randomly generated strings. Why? Suppose you downloaded a few hundred images to use as your desktop wallpaper

null 2 Feb 24, 2022
A small command-line utility for encoding and decoding bech32 strings

A small command-line utility for encoding and decoding bech32 strings.

Charlie Moog 5 Dec 26, 2022
Rust-advent - Learning Rust by solving advent of code challenges (Streaming live on Twitch every Monday)

Rust advent ?? ?? Learning Rust by implementing solutions for Advent of Code problems. ?? HEY, we are live-streaming our attempts to solve the exercis

Luciano Mammino 20 Nov 11, 2022
Rust-clippy - A bunch of lints to catch common mistakes and improve your Rust code

Clippy A collection of lints to catch common mistakes and improve your Rust code. There are over 450 lints included in this crate! Lints are divided i

The Rust Programming Language 8.7k Dec 31, 2022