Skip to content

Instantly share code, notes, and snippets.

@vi
Last active September 10, 2024 02:16
Show Gist options
  • Save vi/6620975b737a1caecf607e88cf6b7fea to your computer and use it in GitHub Desktop.
Save vi/6620975b737a1caecf607e88cf6b7fea to your computer and use it in GitHub Desktop.
List of crates that improves or experiments with Rust, but may be hard to find

Let's list here crates that enhance Rust as a language.

It not "batteries" like in stdx, but Rust-specific crates for workarounds for various missing features and experimental ideals from non-accepted/postponed RFCs, or just hacky tricks.

The list is supposed to contain (mostly) crates that are internal to Rust, not ones for making Rust deal with "external world" like other languages bindings, file formats, protocols and so on.

Primary focus should be on crates that are not easy to find by conventional means (e.g. no algorithm name, format or protocol to search for).

Note that quality of the listed crates may vary from proof-of-concept to stable-and-widely-used.

Procedural macros and custom derive:

  • auto-impl - Derive Box (and other pointers) wrappers with all methods delegated.
  • derive_more - derive standard traits like Add or Index that lack built-in derive.
  • enum-primitive-derive, derive_builder, strum, enum-unitary - derivers for enums; enum-map - "map literal" macro for enums. enumn.
  • smart-default - #[derive(Default)] with your default values.
  • derivative - Some additinoal derives and adjustable analogues of std derives. Debug with ignored fields, Clone with overridden clone function, Default with alternative value like in smart-default. See also: derive-where.
  • couted-array - Automatix size for constant fixed size arrays before RFC 2545 goes in.
  • sugar-rs - List comprehensions, hashmap construction.
  • match_all - A match-like block that executes multiple branches if needed.
  • if_chain - A macro crate that makes embedding a lot of if let nicer. Related: guard for if !let or Swift's guard let.
  • delegate - Proxy struct methods to a field. Also ambassador and portrait.
  • overflower - proc macro that lets you annotate a function to make arithmetic operations in it wrapping, saturating or panicking.
  • def_mod - forward declare mod's interface, asserting that implementation (included by specifying #[path] based on #[cfg]) matches the declared interface.
  • derive_utils - helpers for implementing your own custom derive / macros for enums.
  • interpolate - string interpolation: let world = "world."; s!("Hello, {world}")
  • taken - Sugar for let x = x; or let y = y.clone();, for use in closures.
  • momo - a prototype of automatic introduction of dynamic dispatch in a function using proc macro.
  • ifmt - "inline string {interpolation}"
  • shrinkwraprs - Create Newtype(u32), automatically implementing traits to make as convenient as original type.
  • custom_debug_derive - Derive Debug with a custom format per field.
  • cxx - Generates a bridge between C++ and Rust based on schema defined in Rust code.
  • genawaiter - generators for stable Rust. 3 Types.
  • vecmerge - merge compile-time-known slices of vector literals using + sign.
  • log-derive - auto insert logging for functions
  • cascade - cascade expressions - multiple actions on one object.
  • overloadable - macro function overloading.
  • include-flate - compress literal inlucde_str! / include_bytes! buffer before compilation, lazily decompress in runtime.
  • ambassador - Delegate trait implementations
  • inline-proc - Procedure macros declared and used within the same crate. #[inline_proc] mod ... { }
  • field_names - Generate static array with field names for a struct.
  • syn, quote, proc_macro2 - "Bread and butter" of proc macros. Lightweight alt: venial, myn.

Enum trait

Testing-related

  • test-case-derive - Nightly-only. Allows adding arguments to test functions and listing sets of inputs in attributes.
  • quickcheck, proptest - Fuzz testing. Also mutagen for alternative test coverate method. dicetest.
  • mockiato - Mocking of traits: .expect_myfunc(...).times(2).returns(...)
  • double - mocking (mock testing) library.
  • faux - mocking for testing without traits
  • mockall - #[automock] for traits and other mocking
  • loom - test concurrent code. Also shuttle.
  • insta - snapshot/approval tests helper

Threading and sleeping:

  • spin_sleep - precise sleep.
  • desync Desync<T> where you can post operations to be executed, maybe in background. Alternative approach to threading/syncronosation.
  • crossbeam, rayon - Advanced threading.
  • parking_lot - Synchronisation primitives (Mutex, RwLock, Once) speed up.
  • atomic - generic Atomic<T> type.
  • arc-swap - Arc meets AtomicPtr - Like crossbeam::ArcCell or optimized Mutex<Arc<...>>. Readers don't block. See also: sync_cow
  • atomic_refcell - Threadsafe RefCell.
  • arbalest - Like Arc<AtomicRefCell<T>>, but without some runtime check.
  • qcell - Less flexible, but statically checked RefCell analogue. QCell, LCell, TCell with detached owners for borrowing.
  • flume - mpsc channel, competes with std and crossbeam's. Supports async (including mixing it with sync). Also mp2c. Also postage. Also loole.
  • bus - spmc broadcast lock-free channel.
  • conquer-once - lazy and one-time initialisation, including for nostd

Software transactional memory (STM)

  • swym - transactional memory.
  • stm-core - Clojure-like software transaction memory in Rust. TVar, atomically.
  • lever - STM primitives, also some key-value tables

General list:

  • rental - Deal with self-referential structs. Related: owning_ref - deemed unsound. Related: ouroboros. Related: fortify. Related: yoke. Related: nolife. Related: selfref, broption. self_cell also may be relevant.
  • take_mut, replace_with - Apply Fn(T) -> T to &mut T.
  • type_num / peano - Simulate missing type-level integers.
  • slice - Make a "view" into a Read+Write+Seek with offset and length.
  • mopa - implement customized Any-like trait with your own additional methods. See also: query_interface.
  • streaming_iterator - like Iterator, but with another ownership rules.
  • num, num_traits, alga - Traits for denoting algebraic properties of things and other math; rug - long arithmetic (bigint and friends); caldyn - evaluate strings like "2+2"; nalgebra - linear algebra.
  • failure, error_chain - Dealing with errors in more organized way.
  • downcast-rs, vec_box, traitobject - Tricks with trait objects.
  • optional - a space efficient Option replacement. Related: nanbox.
  • lazy_static - declaring lazily evaluated statics (global variables). See also: core_memo.
  • bytes - Byte array, like subsliceable Arc<Vec<u8>>. Tools: bytes_utils, input_buffer, bufsize.
  • byteorder - io::{Read,Write} for big-endian/little-endian numbers.
  • static_assertions - compile-time assertions.
  • reflect - A proof-of-concept for making Java/Go-like reflections in Rust using procedural macros.
  • boolinator - Option or Result-style methods for bool. Also there's crate bool_ext.
  • noisy_float - Floats that panic on NaN.
  • decorum - Ordered, NonNan and Finite wrappers for floats.
  • smallvec - On-stack small vectors. Tuner: smallvectune.
  • array_tool - More methods for arrays and strings, including a Unicode grapheme iterator.
  • nom, combine, lalrpop - parser combinators
  • serde - serialization. Utils: serde_with crate.
  • mitochondria - MoveCell and OnceCell. Also: once_cell, lazycell, takecell for TakeCell and TakeOwnCell.
  • either - Like Result, but without error semantics.
  • const-concat - A concat! that accepts non-literal strings.
  • void - A crate with a "canonical" uninhabited (zero, bottom) type, to use instead of the ! never type before it goes stable.
  • itertools - More iterator adapters like and related functions like unfold.
  • reexport-proc-macro - Re-export a custom derive.
  • array-macro - Like [42; 3] array literal, but with some restrictions removed.
  • m - pure Rust "libm" - primitive mathematical functions for nostd.
  • interpolate_idents - more powerful concat_idents!. Also paste.
  • null-terminated - NULL-terminated arrays for C interop.
  • bus - Single writer, multiple reader broadcast lockfree communication channel. std::io::{Read,Write} wrapper: bus-writer.
  • frunk - Functinal programming toolkit: HList (heterogenous list of cons cell), Coproduct for ad-hoc enums, Semigroup/Monoid like in alga above.
  • fragile - Fragile<T> and Sticky<T> wrappers for sending non-Send things across threads.
  • joinery - join_with for joining to a string with separators from an Iterator.
  • pipe - Generate a byte stream-based pipe, like std::sync::mpsc, but for bytes. Combined with my crate readwrite you can make it bi-directional, like a socket. Also newer crate duplexify.
  • uninitialized - Choose std::mem::zeroed or std::mem::uninitialized based on Cargo feature flag.
  • failsafe - wrap function in a supervisor that prohibits execution (returns error early) for some time in case of consequtive failures of the wrapped function. Also recloser.
  • corona - stackful coroutines. Also coro.
  • subtle - constant-time primitive ops for crypto
  • ctor - life before main() - auto-initialization of things before main() using linker tricks. Also https://crates.io/crates/startup .
  • inventory - Typed distributed plugin registration using ctor crate above.
  • strfmt - Like format!(), but with dynamically specified format string and your hashmap for available variables.
  • panic-never - Panic handler for no_std code that causes linker error if panics are not statically excluded from your code. Also no-panics-whatsoever.
  • stdio-override - Override std::io::std{in,out,err} using dup2 on Unix.
  • bstr - Text processing methods for UTF-8-esque byte strings.
  • async-trait - Traits for async fn using dynamic dispatch. See also https://crates.io/crates/real-async-trait. See also: polling-async-trait, async-trait-ext
  • pow - insert proof-of-work requirements using serde
  • zerocopy - Utilities for zero-copy parsing and serialization
  • scopeguard - defer!, defer_on_unwind!, defer_on_success!.
  • bytemuck - Zeroable, Pod (plain old data) trait, safe reinterpret_casts for some types.

Allocation or data structures:

  • slab - Hands out integer handles instead of actual pointers. My own additions: slab_typesafe, compactmap.
  • non-empty, vec1 - A non-empty vector or maybe other things. See also a reddit thread.
  • lru_time_cache - A cache. timed_cache - another cache. Also cached even has #[cached] for memoized functions. Also schnellru.
  • uluru - Another LRU cache.
  • im, rpds - Immutable collection data types.
  • fst - Specialized compact data structure for pre-ordered data.
  • internment - Interning strings or data. Stores data permanently/to Rc/to Arc and gives a handle. Same data => same handle. See also: lasso
  • tendril - compact string/buffer type, optimized for zero-copy parsing.
  • slotmap - like slab, but handles are protected against accidental reuse (there is counter inside).
  • froggy - like slab, but with iteration, reference counting and weak pointers.
  • containers - containers like in std, but with fallible allocation and custom allocators.
  • sdset - A wrapper around a sorted+deduplicated slice providing faster set operations (union, intersection, etc.).
  • intrusive-collections - no_std single- and double-linked lists, red-black tree without allocating dedicated memory for them, but by attaching things to contained objects instead.
  • phf - compile-time-constructed static perfect hash table maps and sets.
  • generational-arena - Safe allocator with deletions. Like slotmap. Also thunderdome.
  • rctree - DOM-like tree with ordered children, parents and siblings, based on strong and weak Rc links.
  • heapless - allocation-free data structures: fixed-size vec, priority queue, hash table/set.
  • voluntary-servitude - thread-safe appendable list with lock-free iterator.
  • copyless - Pre-allocate Box or Vec entry to fill it in later. Also maybe prevents extra memcpy call.
  • ccl - Fast concurrent hashmap and timed cache, also for no_std. See also dashmap and chashmap. shard_lock.
  • contrie - Lock-free concurrent map and set with interface similar to HashMap.
  • Evmap - A lock-free, eventually consistent, concurrent multi-value map.
  • sharded_slab - Slab mutable without exclusive access, lockfree
  • arrayvec - Array-backed fixed-capacity vector
  • vec-utils - map and zip vector while reusing allocation.
  • elsa - append-only collections for getting references to elements. Insertion does not require exclusive (&mut) access. Store indirected (Box/Vec/String) data and hold shared references across insertions.
  • shawshank - generic internment.
  • concache - Two fast concurrent shared hash maps.
  • hashcow - Hash table with copy-on-write for storing duplicated data.
  • coca - Data Structures with Constant Capacity.
  • inplace_it - inplace_or_alloc_array Place small arrays on the stack.
  • la-arena - simple Vec-based deletion-less arena

Cargo-specific or code analysers:

Hosted languages designed to interoperate with Rust

  • Rhai - small, inspired by Chai.
  • Rune - async-friendly
  • Dyon
  • Mun

https://www.boringcactus.com/2020/09/16/survey-of-rust-embeddable-scripting-languages.html

Unsorted links dump

(to be moved up and described properly)

Various types of Arc/Rc with or without weak counter: https://internals.rust-lang.org/t/add-a-smart-pointer-with-only-strong-references-count/17635/7

"If you're looking to get structs (possibly dynamically sized) consider using zerocopy (or scroll, or structview). If you need to turn bytes into trivial types such as u16 or arrays thereof, use bytemuck (or safe-transmute)."

https://github.com/rosetta-rs/parse-rosetta-rs - comparison (and list) of various parsers

https://blessed.rs/crates - another list of crates

https://github.com/BurntSushi/rsc-regexp - three rewrites of a pointer-heavy and tricky C program into Rust, for educational purposes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment