mod builder;
mod checkpoint;
mod display;
mod queue;
pub use builder::Builder;
pub use checkpoint::Checkpoint;
pub use display::Display;
pub use queue::Queue;
use crate::socket::Slot;
use crate::{At, Edit, Entry, Event, Record};
use alloc::collections::VecDeque;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use core::mem;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use slab::Slab;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct History<E, S = ()> {
root: usize,
saved: Option<At>,
record: Record<E, S>,
branches: Slab<Branch<E>>,
}
impl<E> History<E> {
pub fn new() -> History<E> {
History::builder().build()
}
}
impl<E, S> History<E, S> {
pub fn builder() -> Builder<E, S> {
Builder::default()
}
pub fn reserve(&mut self, additional: usize) {
self.record.reserve(additional);
}
pub fn capacity(&self) -> usize {
self.record.capacity()
}
pub fn shrink_to_fit(&mut self) {
self.record.shrink_to_fit();
}
pub fn len(&self) -> usize {
self.record.len()
}
pub fn is_empty(&self) -> bool {
self.record.is_empty()
}
pub fn limit(&self) -> usize {
self.record.limit()
}
pub fn connect(&mut self, slot: S) -> Option<S> {
self.record.connect(slot)
}
pub fn disconnect(&mut self) -> Option<S> {
self.record.disconnect()
}
pub fn is_saved(&self) -> bool {
self.record.is_saved()
}
pub fn saved(&self) -> Option<At> {
self.record
.saved
.map(|index| At::new(self.root, index))
.or(self.saved)
}
pub fn can_undo(&self) -> bool {
self.record.can_undo()
}
pub fn can_redo(&self) -> bool {
self.record.can_redo()
}
pub fn head(&self) -> At {
At::new(self.root, self.record.head())
}
pub fn next_branch_head(&self) -> Option<At> {
self.branches
.iter()
.find(|&(id, _)| id > self.root)
.map(|(id, branch)| At::new(id, branch.parent.index + 1))
}
pub fn prev_branch_head(&self) -> Option<At> {
self.branches
.iter()
.rfind(|&(id, _)| id < self.root)
.map(|(id, branch)| At::new(id, branch.parent.index + 1))
}
pub fn get_entry(&self, index: usize) -> Option<&Entry<E>> {
self.record.get_entry(index)
}
pub fn entries(&self) -> impl Iterator<Item = &Entry<E>> {
self.record.entries()
}
pub fn get_branch(&self, id: usize) -> Option<&Branch<E>> {
self.branches.get(id)
}
pub fn branches(&self) -> impl Iterator<Item = (usize, &Branch<E>)> {
self.branches.iter()
}
pub fn queue(&mut self) -> Queue<E, S> {
Queue::from(self)
}
pub fn checkpoint(&mut self) -> Checkpoint<E, S> {
Checkpoint::from(self)
}
pub fn display(&self) -> Display<E, S> {
Display::from(self)
}
fn rm_child_of(&mut self, at: At) {
let mut dead: Vec<_> = self
.branches()
.filter(|&(_, child)| child.parent == at)
.map(|(id, _)| id)
.collect();
while let Some(id) = dead.pop() {
self.branches.remove(id);
self.saved = self.saved.filter(|s| s.root != id);
dead.extend(
self.branches()
.filter(|&(_, child)| child.parent.root == id)
.map(|(id, _)| id),
)
}
}
fn mk_path(&mut self, mut to: usize) -> Option<impl Iterator<Item = (usize, Branch<E>)> + use<E, S>> {
debug_assert_ne!(self.root, to);
let mut dest = self.nil_replace(to)?;
let mut i = dest.parent.root;
let mut path = alloc::vec![(to, dest)];
while i != self.root {
dest = self.nil_replace(i).unwrap();
to = i;
i = dest.parent.root;
path.push((to, dest));
}
Some(path.into_iter().rev())
}
fn nil_replace(&mut self, id: usize) -> Option<Branch<E>> {
let dest = self.branches.get_mut(id)?;
let dest = mem::replace(dest, Branch::NIL);
Some(dest)
}
}
impl<E, S: Slot> History<E, S> {
pub fn set_saved(&mut self) {
self.saved = None;
self.record.set_saved();
}
pub fn clear_saved(&mut self) {
self.saved = None;
self.record.clear_saved();
}
pub fn clear(&mut self) {
let old_root = self.root;
self.saved = None;
self.record.clear();
self.branches.clear();
self.root = self.branches.insert(Branch::NIL);
self.record
.socket
.emit_if(old_root != self.root, || Event::Root(self.root));
}
fn set_root(&mut self, new: At, rm_saved: Option<usize>) {
debug_assert_ne!(self.root, new.root);
self.branches
.iter_mut()
.filter(|(_, child)| child.parent.root == self.root && child.parent.index <= new.index)
.for_each(|(_, child)| child.parent.root = new.root);
match (self.saved, rm_saved) {
(Some(saved), None) if saved.root == new.root => {
self.saved = None;
self.record.saved = Some(saved.index);
}
(None, Some(saved)) => {
self.saved = Some(At::new(self.root, saved));
}
_ => (),
}
debug_assert_ne!(self.saved.map(|s| s.root), Some(new.root));
self.root = new.root;
self.record.socket.emit(|| Event::Root(new.root));
}
}
impl<E: Edit, S: Slot> History<E, S> {
pub fn edit(&mut self, target: &mut E::Target, edit: E) -> E::Output {
let head = self.head();
let (output, merged, tail, rm_saved) = self.record.edit_and_push(target, Entry::new(edit));
if !merged && head.index == self.record.head() {
let root = self.root;
self.rm_child_of(At::new(root, 0));
self.branches
.iter_mut()
.filter(|(_, child)| child.parent.root == root)
.for_each(|(_, child)| child.parent.index -= 1);
}
if !tail.is_empty() {
let next = self.branches.insert(Branch::NIL);
let new = At::new(next, head.index);
let root = self.branches.get_mut(head.root).unwrap();
debug_assert!(root.entries.is_empty());
root.parent = new;
root.entries = tail;
self.set_root(new, rm_saved);
}
output
}
pub fn undo(&mut self, target: &mut E::Target) -> Option<E::Output> {
self.record.undo(target)
}
pub fn redo(&mut self, target: &mut E::Target) -> Option<E::Output> {
self.record.redo(target)
}
pub fn revert(&mut self, target: &mut E::Target) -> Vec<E::Output> {
let Some(saved) = self.saved() else {
return Vec::new();
};
self.go_to(target, saved)
}
pub fn go_to(&mut self, target: &mut E::Target, at: At) -> Vec<E::Output> {
if self.root == at.root {
return self.record.go_to(target, at.index);
}
let Some(path) = self.mk_path(at.root) else {
return Vec::new();
};
let mut outputs = Vec::new();
for (id, branch) in path {
let mut outs = self.record.go_to(target, branch.parent.index);
outputs.append(&mut outs);
for entry in branch.entries {
let index = self.record.head();
let (_, _, entries, rm_saved) = self.record.redo_and_push(target, entry);
if !entries.is_empty() {
let new = At::new(id, index);
let root = self.branches.get_mut(self.root).unwrap();
debug_assert!(root.entries.is_empty());
root.parent = new;
root.entries = entries;
self.set_root(new, rm_saved);
}
}
}
let mut outs = self.record.go_to(target, at.index);
outputs.append(&mut outs);
outputs
}
}
impl<E: fmt::Display, S> History<E, S> {
pub fn undo_string(&self) -> Option<String> {
self.record.undo_string()
}
pub fn redo_string(&self) -> Option<String> {
self.record.redo_string()
}
}
impl<E> Default for History<E> {
fn default() -> History<E> {
History::new()
}
}
impl<E, S> From<Record<E, S>> for History<E, S> {
fn from(record: Record<E, S>) -> Self {
let mut branches = Slab::new();
let root = branches.insert(Branch::NIL);
History {
root,
saved: None,
record,
branches,
}
}
}
impl<E, F> From<History<E, F>> for Record<E, F> {
fn from(history: History<E, F>) -> Record<E, F> {
history.record
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct Branch<E> {
parent: At,
entries: VecDeque<Entry<E>>,
}
impl<E> Branch<E> {
const NIL: Branch<E> = Branch {
parent: At::NIL,
entries: VecDeque::new(),
};
pub fn parent(&self) -> At {
self.parent
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn get_entry(&self, index: usize) -> Option<&Entry<E>> {
self.entries.get(index)
}
pub fn entries(&self) -> impl Iterator<Item = &Entry<E>> {
self.entries.iter()
}
}