# overlay-map
**overlay-map** is a two-layered map data structure for Rust that allows for non-destructive updates by maintaining both a **foreground** (mutable) and a **background** (read-only) value layer for each key.
Itβs designed for scenarios where you want to:
- Apply temporary or just-in-time changes without mutating original data.
- Implement overlays, deltas, rollback-able changes, or speculative state changes.
- Avoid cloning/copying values unnecessarily on update.
> β οΈ **Work in progress**: This library is still evolving. Planned features
> include thread-safe version, rollback support, and a wider API.
## π¦ Features
- β
Foreground and background storage per key
- β
On insert, the old foreground is pushed to background (only **one** previous value is retained β not a full history)
- β
If a key exists, its foreground is **always** present β no fallback logic is required during reads
- β
Zero-cost value pushing (via in-place pointer tricks)
- β
No cloning required on push
- β
Optional conditional pushes (`push_if`)
- β
Extendable from other maps
## π Example
```rust
use overlay_map::OverlayMap;
#[derive(Debug, Clone, PartialEq)]
struct QuantumBit {
collapsed: bool,
value: Option<bool>,
}
/// Simulates measurement collapse
fn collapse(mut qbit: QuantumBit) -> QuantumBit {
qbit.collapsed = true;
qbit.value = Some(rand::random());
qbit
}
fn main() {
let mut qstate = OverlayMap::<&str, QuantumBit>::new();
// Push an uncollapsed qubit
qstate.push(
"qbit_1",
QuantumBit {
collapsed: false,
value: None,
},
);
// Observe the qubit: only collapse if it's not already
let did_observe = qstate.push_if(&"qbit_1", |current| {
if current.collapsed {
None // already collapsed, don't change
} else {
Some(collapse(current.clone())) // clone *only* if needed
}
});
println!("Was observed? {}", did_observe);
println!("After observation: {:?}", qstate.fg(&"qbit_1"));
println!("Before observation: {:?}", qstate.bg(&"qbit_1"));
}
```
## π§ Why?
This is useful when:
- You want to track *current vs previous* state (not full history).
- You're doing **speculative updates** or **rollback systems** (planned).
- You need **non-destructive overlays** (e.g. config layering, versioning, etc).
- You want to avoid expensive cloning when replacing data.
## π Documentation
- [Docs.rs](https://docs.rs/overlay-map)
- [Crates.io](https://crates.io/crates/overlay-map)
## π License
MIT
## β¨ Contributing
Contributions, bug reports, and feature requests welcome.
Planned areas of work:
- Thread-safe version
- Rollback support
- More expressive APIs