[](./LICENSE.txt)
[](https://crates.io/crates/journalmap)
[](https://docs.rs/journalmap)
## Journaling data storage types for easy version control and undo + redo
`journalmap`, which was originally made for my side hustle [Mjolnir](https://blacksheepswe.dev/mjolnir/)
, is a crate meant to provide analog to common data storage types with built-in
journaling, meaning each write transaction is recorded so that you can easily
undo and redo operations. The end user treats these data types like you would a
normal Vec or HashMap, except they can add "tags", basically generic markers
that can be traveled to, to either undo a change, redo a change, or check out a
previous version of the data.
## Example
Below is an example of a JournalVec.
```rust
use journalmap::JournalVec;
fn main() {
let mut rsvp: JournalVec<&'static str, _> = JournalVec::new();
// Always add a tag at the start
rsvp.append_tag("start").unwrap();
rsvp.push("Sarah");
rsvp.push("John");
rsvp.push("Mariah");
rsvp.insert(1, "Steve");
rsvp.append_tag("middle").unwrap();
rsvp.pop();
rsvp.remove(1);
rsvp.append_tag("end").unwrap();
// Now let's reverse it and watch our changes be undone...
rsvp.reverse_to_next();
assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah"]);
// We can also redo the changes we've applied
rsvp.forward_to_tag(&"end");
assert_eq!(rsvp.as_slice(), &["Sarah", "John"]);
rsvp.reverse_to_next();
// Inserting a new entry truncates the future so we can no longer
// re-do the changes we've undone
rsvp.push("Omar");
rsvp.append_tag("end").unwrap();
assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah", "Omar"]);
}
```
## Flags
* `serde` - enables serde-based serialization and deserialization of journals.