pub struct Store<D, X = ()> { /* private fields */ }Expand description
Owns a document D and its undo history.
- Reads are free:
Store::docborrows the current snapshot,Store::snapshotclones theArcfor a job or another thread. - Edits are copy-on-write: the closure gets a fresh copy (
Arc::make_mutwhile the history still holds the old state), so its cost isD::clone. MakeDcheap to clone by keeping large parts inArcs (chunks, tracks, pages); an edit then copies only the chunk it touches. - Every change gets a new
Revision; undo and redo restore the revision of the state they bring back, so caches keyed by revision stay valid andStore::is_dirtyis exact. Xis extra state recorded with each step and restored by undo/redo (selection, caret). It can be changed freely withStore::extra_mutwithout making a step.
Implementations§
Source§impl<D: Clone, X: Clone> Store<D, X>
impl<D: Clone, X: Clone> Store<D, X>
Sourcepub fn with_extra(doc: D, extra: X) -> Store<D, X>
pub fn with_extra(doc: D, extra: X) -> Store<D, X>
A store holding doc with extra state extra, considered saved.
Sourcepub fn snapshot(&self) -> Arc<D> ⓘ
pub fn snapshot(&self) -> Arc<D> ⓘ
The current document, to keep or send to another thread (an Arc clone).
pub fn revision(&self) -> Revision
pub fn extra(&self) -> &X
pub fn history(&self) -> &History<D, X>
Sourcepub fn history_mut(&mut self) -> &mut History<D, X>
pub fn history_mut(&mut self) -> &mut History<D, X>
The history, to change its limits or squash steps.
Sourcepub fn edit<R>(&mut self, label: &str, f: impl FnOnce(&mut D) -> R) -> R
pub fn edit<R>(&mut self, label: &str, f: impl FnOnce(&mut D) -> R) -> R
Apply an undoable edit called label.
Sourcepub fn try_edit<R, E>(
&mut self,
label: &str,
f: impl FnOnce(&mut D) -> Result<R, E>,
) -> Result<R, E>
pub fn try_edit<R, E>( &mut self, label: &str, f: impl FnOnce(&mut D) -> Result<R, E>, ) -> Result<R, E>
Apply an edit that may fail; on error (or a panic in f) nothing changes.
Sourcepub fn edit_merged<R>(
&mut self,
label: &str,
merge_key: &str,
f: impl FnOnce(&mut D) -> R,
) -> R
pub fn edit_merged<R>( &mut self, label: &str, merge_key: &str, f: impl FnOnce(&mut D) -> R, ) -> R
Store::edit that folds into the previous step when that step has the same label and
was made with the same merge_key with nothing in between (one undo step per drag).
Sourcepub fn try_edit_with<R, E>(
&mut self,
label: &str,
merge_key: Option<&str>,
f: impl FnOnce(&mut D, &mut X) -> Result<R, E>,
) -> Result<R, E>
pub fn try_edit_with<R, E>( &mut self, label: &str, merge_key: Option<&str>, f: impl FnOnce(&mut D, &mut X) -> Result<R, E>, ) -> Result<R, E>
The general edit: optional merge key, access to the extra state, may fail. On error (or a
panic in f) the document, the extra state, the revision and the history are unchanged.
Sourcepub fn commit(&mut self, label: &str, merge_key: Option<&str>, doc: Arc<D>)
pub fn commit(&mut self, label: &str, merge_key: Option<&str>, doc: Arc<D>)
Make doc, built elsewhere (a command’s working copy, a job’s result), the new state as
one undo step label, without copying it. merge_key as in Store::edit_merged.
Committing the current snapshot itself (Arc::ptr_eq) changes nothing.
Sourcepub fn transaction<T, E>(
&mut self,
label: &str,
f: impl FnOnce(&mut Store<D, X>) -> Result<T, E>,
) -> Result<T, E>
pub fn transaction<T, E>( &mut self, label: &str, f: impl FnOnce(&mut Store<D, X>) -> Result<T, E>, ) -> Result<T, E>
Run f, which may make any number of edits, as one undo step called label.
On Ok the edits fold into one step (none when they changed nothing); the steps before
the transaction are untouched and the redo line is dropped only if something changed. On
Err, or a panic in f, the document, extra state, revision, history (redo line and merge
key included) and saved state are put back as they were. See Transaction.
Sourcepub fn begin_transaction(&mut self, label: &str) -> Transaction<'_, D, X>
pub fn begin_transaction(&mut self, label: &str) -> Transaction<'_, D, X>
Start a Transaction called label: edit through it, then Transaction::commit;
dropping it without committing (an early return, a panic) rolls everything back.
Sourcepub fn transaction_on<H, T, E>(
host: &mut H,
store: impl Fn(&mut H) -> &mut Store<D, X>,
label: &str,
f: impl FnOnce(&mut H) -> Result<T, E>,
) -> Result<T, E>
pub fn transaction_on<H, T, E>( host: &mut H, store: impl Fn(&mut H) -> &mut Store<D, X>, label: &str, f: impl FnOnce(&mut H) -> Result<T, E>, ) -> Result<T, E>
Store::transaction for a host that owns the store: f gets the whole host (to run
commands that take &mut H), store finds the store in it. Same semantics: one step on
Ok, everything put back on Err or a panic in f (the panic then continues), nesting
as a savepoint, nothing recorded when nothing changed.
struct Host { store: Store<Vec<i32>>, runs: u32 }
let mut host = Host { store: Store::new(Vec::new()), runs: 0 };
let r: Result<(), ()> = Store::transaction_on(&mut host, |h| &mut h.store, "Two", |h| {
h.runs += 1;
h.store.edit("a", |d| d.push(1));
h.store.edit("b", |d| d.push(2));
Ok(())
});
assert_eq!(r, Ok(()));
assert_eq!(host.store.history().undo_labels().collect::<Vec<_>>(), ["Two"]);Sourcepub fn redo_branch(&mut self, index: usize) -> Option<String>
pub fn redo_branch(&mut self, index: usize) -> Option<String>
Redo into branch index of History::branches (it must grow from the current state).
pub fn can_undo(&self) -> bool
pub fn can_redo(&self) -> bool
Sourcepub fn replace(&mut self, doc: D, extra: X)
pub fn replace(&mut self, doc: D, extra: X)
Replace the whole document (New, Open, Revert): clears the history, counts as saved.
Sourcepub fn mark_saved(&mut self)
pub fn mark_saved(&mut self)
The current state was saved.
Sourcepub fn mark_saved_at(&mut self, revision: Revision)
pub fn mark_saved_at(&mut self, revision: Revision)
Record that the state with revision was saved (a background save of an older snapshot).
pub fn saved_revision(&self) -> Revision
Sourcepub fn subscribe_snapshots(&mut self) -> Arc<SnapshotCell<D>> ⓘ
pub fn subscribe_snapshots(&mut self) -> Arc<SnapshotCell<D>> ⓘ
A cell other threads read the latest snapshot from without locking; the store publishes every change to it. The same cell is returned on every call.