List of crates that improves or experiments with Rust, but may be hard to find


#1

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.

Custom derive-oriented:

  • 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.
  • 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.
  • test-case-derive - Nightly-only. Allows adding arguments to test functions and listing sets of inputs in attributes.
  • couted-array - Automatix size for constant fixed size arrays before RFC 2545 goes in.

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.

General list:

  • rental - Deal with self-referential structs. Related: owning_ref.
  • take_mut - 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.
  • if_chain - A macro crate that makes embedding a lot of if let nicer. Related: guard
  • 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, byteorder - Work with byte arrays (big-endian/little-endian).
  • static_assertions - compile-time assertions.
  • reflect - A proof-of-concept for making Java/Go-like reflections in Rust using procedural macros.
  • delegate - Proxy struct methods to a field.
  • noisy_float - Floats that panic on NaN.
  • smallvec - On-stack small vectors. Tuner: smallvectune.
  • match_all - A match-like block that executes multiple branches if needed.
  • array_tool - More methods for arrays and strings, including a Unicode grapheme iterator.
  • quickcheck, proptest - Fuzz testing. Also mutagen for alternative test coverate method.
  • nom, combine, lalrpop - parser combinators
  • serde - serialization
  • mitochondria - MoveCell and OnceCell. Also: once_cell, lazycell.
  • either - Like Result, but without error semantics.
  • boolinator - Option or Result-style methods for bool.
  • coalesce - Join mismatched if/match branches based on enum, alternative to usage of a trait object. See also: impl_sum.
  • 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!.
  • 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.
  • double - mocking (mock testing) library.
  • 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.
  • 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.

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.
  • 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.
  • 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.

Cargo-specific, testing or related tools:

  • cargo bloat - Show what takes space in your binary
  • cargo license, cargo-lichking - List all dependencies by licence.
  • cargo outdated - Show which packages have newer version available.
  • cargo clippy - Additional warnings
  • cargo fmt (rustfmt) - Automatically format the code. Also installable by rustup.
  • cargo geiger - Measure “unsafeness” of the project by counting expressions in unsafe{} blocks and other unsafe things. Prototype: cargo-osha
  • cargo make - Define and run targets in a toml file like in Makefile.
  • cargo add, cargo rm and so on - Manage dependencies from command line.
  • cargo tarpaulin - code coverage for tests.
  • cargo asm - display the assembly or llvm-ir generated for Rust source code (a single function can be specified).
  • cargo audit - Scan dependencies (Cargo.lock) for reported security vulnerabilities.

Please suggest additions, replacements or removals.


#2

There’s a peano crate, succeeded by typenum.


#3

optional - a space efficient Option replacement.


#4

lazy_static - declaring lazily evaluated statics.


#5

Is this still needed with the new notch optimizations? The readme says

Not only does OptionBool improve space efficiency as opposed to Option<bool>

But nowadays bool, Option<bool>, and even Option<Option<bool>> and beyond are all the same size.


#6

I think the original bool use case is gone, but I could see myself using that crate for storing optional floats, using NaN as the None value.


#7

That’s exactly what I plan to use it for.


#8

typenum has no underscore nor does it use a lowly Peano encoding (it’s a binary encoding!)

(edit: okay the peano thing was fixed, but that underscore is still there silently taunting at me)


#9

I tried to be careful how I mentioned peano followed by typenum:man_shrugging:


#10

https://crates.io/crates/static_assertions


#11

Extended the list from relevant “Crate of the Week” posts.


#12

Can you please link the ‘cargo-specific or related tools’ section?


#13

Done.


#14

cargo license - List all dependencies by licence. There is also some alternative implementation, but I forgot the name.

cargo-lichking. Haven’t researched them for their strengths or weaknesses.


#15

proptest probably derserves a mention alongside quickcheck :slight_smile:


#16

Maintainer of optional here. I was about to deprecate OptionBool when re-running the benchmarks still showed some measurable differences. So yes, it no longer has a space advantage, but it may sometimes have a time advantage.

Even without OptionBool, the crate still has option replacements for other types.


#17

Have you filed bugs for those?


#18

cargo-make rust build tool and task runner.
comes with many default tasks to make any project development easier and automated.


#19

rules was an incomplete experiment to bring Perl 6 style regex to rust. There is a lot which could be done to extend the project. I’m not sure if this is the type of thing you’re looking for.

I definitely think this type of thing might be really positive in the long run but it would have be more fully implemented to verify in any fashion.


#20

I made some crates that I think could fit onto the list.

  • array-macro - vec![something; 4] for arrays, not requiring a Copy implementation
  • reexport-proc-macro - probably useless with Rust 2018 where you can go pub use crate_derive::Trait, but allows reexporting a procedural derive, not requiring an user of a crate to have a dependency on derive crate
  • https://crates.io/crates/enum-map - just like EnumMap in Java, except for Rust, a map implementation optimized for enums implemented as an array