🔑 KeyPaths & CasePaths in Rust
Key paths and case paths provide a safe, composable way to access and modify nested data in Rust. Inspired by Swift’s KeyPath / CasePath system, this feature rich crate lets you work with struct fields and enum variants as first-class values.
✨ Features
- ✅ Readable/Writable keypaths for struct fields
- ✅ Failable keypaths for
Option<T>chains (_fr/_fw) - ✅ Enum CasePaths (readable and writable prisms)
- ✅ Composition across structs, options and enum cases
- ✅ Iteration helpers over collections via keypaths
- ✅ Proc-macros:
#[derive(Keypaths)]for structs/tuple-structs and enums,#[derive(Casepaths)]for enums
📦 Installation
[]
= "1.0.0"
= "0.4"
🚀 Examples
See examples/ for many runnable samples. Below are a few highlights.
Widely used - Deeply nested struct
use KeyPaths;
use ;
Iteration via keypaths
use KeyPaths;
;
/*
ABox { name: "A box", size: Size { width: 10, height: 20 }, color: Other(RGBU8(10, 20, 30)) }
ABox { name: "A box", size: Size { width: 10, height: 20 }, color: Other(RGBU8(0, 0, 0)) }
*/
📦 Container Adapters & References (NEW!)
KeyPaths now support smart pointers, containers, and references via adapter methods:
Smart Pointer Adapters
Use .for_arc(), .for_box(), or .for_rc() to adapt keypaths for wrapped types:
use Arc;
let products: = vec!;
// Adapt keypath to work with Arc<Product>
let price_path = price_r.for_arc;
let affordable: = products
.iter
.filter
.collect;
Reference Support
Use .get_ref() and .get_mut_ref() for collections of references:
let products: = hashmap.values.collect;
let price_path = price_r;
for product_ref in &products
Supported Adapters:
.for_arc()- Works withArc<T>(read-only).for_box()- Works withBox<T>(read & write).for_rc()- Works withRc<T>(read-only).get_ref()- Works with&Treferences.get_mut_ref()- Works with&mut Treferences
Examples:
examples/container_adapters.rs- Smart pointer usageexamples/reference_keypaths.rs- Reference collectionskey-paths-core/examples/container_adapter_test.rs- Test suite
Documentation: See CONTAINER_ADAPTERS.md and REFERENCE_SUPPORT.md
🔗 Helpful Links & Resources
- 📘 type-safe property paths
- 📘 Swift KeyPath documentation
- 📘 Elm Architecture & Functional Lenses
- 📘 Rust Macros Book
- 📘 Category Theory in FP (for intuition)
💡 Why use KeyPaths?
- Avoids repetitive
match/.chains. - Encourages compositional design.
- Plays well with DDD (Domain-Driven Design) and Actor-based systems.
- Useful for reflection-like behaviors in Rust (without unsafe).
🛠Roadmap
- Compose across structs, options and enum cases
- Derive macros for automatic keypath generation
- Optional chaining with failable keypaths
- [] Derive macros for complex multi-field enum variants
📜 License
- Mozilla Public License 2.0