Expand description
§Rust Programming Patterns
This repository is a curated and growing collection of Rust programming patterns, idioms, and implementation techniques drawn from real-world systems programming, language design, and library development. I might also include opinionated best practices.
Many of these examples were developed or collected during work on ixa — an agent-based modeling framework that makes heavy use of reflection and plugin-like systems, which explains the bias towards those themes here. Some ideas come from my work on mod2, a Rust implementation of some of the advanced pattern matching algorithms in Maude.
Some of the ideas represented here are idiomatic Rust rediscoveries of much older techniques from systems programming, functional programming, and type theory (for example, patterns inspired by Haskell’s type-level design or ML-style module systems). While these patterns are well-known across programming language communities, their practical and idiomatic realization in Rust is of particular interest here.
Goals:
-
illustration of ideas, not (necessarily) production quality implementation — adapt to your use case or use an existing crate
-
zero-cost abstractions
-
general applicability
-
Rust-specific context
Major Themes:
- Type-indexed data and reflection
- Registries and plugin systems
- Hashing and map design
- Type-erased vs. strongly typed APIs
- Strategies for initialization / separation of mutable and immutable accesses.
- Memory ownership and life cycle management
Similar Efforts:
Anyone interested in this repo will almost certainly want to study Rust Design Patterns (rust-unofficial), a documented catalogue of idiomatic Rust patterns, anti-patterns, and community conventions. Includes behavioural, structural, and creational patterns.
§How to Read
The idea is to read the docs like a book. The docs are rendered on GitHub Pages: https://www.robertjacobson.dev/rust_patterns/rust_patterns/
Commentary is provided in doc comments and in the source code itself. Sometimes there isn’t a doc comment that is a good fit for something I have to say, so I’ll but information in a module-level doc comment. There isn’t a perfect solution. Hopefully it’s still useful.
§Authorship, Attribution, and License
Copyright © 2025 Robert Jacobson. This software is distributed under the terms of the MIT license or the Apache 2.0 license at your preference.
This collection represents a blend of:
- techniques independently developed or refined during work on Rust projects such as ixa.
- patterns that are well-established in the wider systems, functional, and language-theory communities.
- idiomatic Rust implementations of known ideas — often inspired by patterns that have evolved organically within the Rust community itself.
Although the implementations and commentary here are original (to the extent that even means anything, as some are also trivial), the underlying ideas are shared heritage within decades of programming language development. This repository is intended in that spirit — as a documentation of understanding, adaptation, and synthesis, rather than as a claim of invention.
§Ideas That Do Not Yet Have a Home
§Correctness via Macro
There are many ways to enforce “correctness” in a computer program:
- the type system: data types, method signatures
- ownership model: borrowing, lifetimes, RAII techniques, copy/move semantics
- visibility/access control: packages, modules, namespaces
- exhaustiveness checking
- bounds checking
- etc.
The best situation is when the compiler can enforce correctness with as little engagement as possible from the programmer; correctness just “happens” without manually having to be checked and without the programmer having to write a lot of code to ensure it.
But this is not always possible. Consider the case of plugin systems, which
have some degree of automatic discovery of plugins across crate boundaries. In such a case, the
library author is not in control of the code that defines the plugin. Rust’s orphan/coherence rules
prevent the library author from writing implementation on behalf of client code. So how can the
library author ensure that the implementation of a plugin defined in client code is correct? By
providing the implementation in client code through a macro that can realize the implementation in
the context of the client crate. A concrete example is given in the registered_item_impl macro.
Unfortunately, there is no mechanism to require that client code use the macro to implement a plugin. Also, Rust macros have exactly the same access and limitations as any other client code, so the implementation they provide is not equivalent to other information hiding mechanisms. Finally, the correctness of the implementation the macro generates is obviously only correct if the macro itself is correct.
Modules§
- hashing
- Hiding the Backing Implementation of Algorithms and Data Structures
- plugins
- Plugin Systems in Rust
- shared_
implementation - Information Hiding, Encapsulation, and Shared Implementation
- type_
erased_ api - Typed and Type-Erased API
Macros§
- registered_
item_ impl - This macro ensures correct implementation of the
RegisteredItemtrait. The tricky bit is the implementation ofRegisteredItem::index, which requires synchronization in multithreaded runtimes. This is an instance of correctness via macro.