pub struct AutoCommit { /* private fields */ }
Expand description
An automerge document that automatically manages transactions.
§Creating, loading, merging and forking documents
A new document can be created with Self::new()
, which will create a document with a random
ActorId
. Existing documents can be loaded with Self::load()
.
If you have two documents and you want to merge the changes from one into the other you can use
Self::merge()
.
If you have a document you want to split into two concurrent threads of execution you can use
Self::fork()
. If you want to split a document from ealier in its history you can use
Self::fork_at()
.
§Reading values
Self
implements ReadDoc
, which provides methods for reading values from the document.
§Modifying a document
This type implements Transactable
directly, so you can modify it using methods from Transactable
.
§Synchronization
To synchronise call Self::sync()
which returns an implementation of SyncDoc
§Patches, maintaining materialized views
AutoCommit
allows you to generate Patch
es representing changes to the current state of
the document which you can use to maintain a materialized view of the current state. There are
several ways to use this. See the documentation on Self::diff()
for more details, but the key
point to remember is that AutoCommit
manages an internal “diff cursor” for you. This is a
representation of the heads of the document last time you called Self::diff_incremental()
but you can also manage it directly using Self::update_diff_cursor()
and
Self::reset_diff_cursor()
.
Implementations§
Source§impl AutoCommit
impl AutoCommit
pub fn new() -> AutoCommit
pub fn new_with_encoding(encoding: TextEncoding) -> AutoCommit
pub fn load(data: &[u8]) -> Result<Self, AutomergeError>
pub fn load_unverified_heads(data: &[u8]) -> Result<Self, AutomergeError>
pub fn load_with( data: &[u8], on_error: OnPartialLoad, mode: VerificationMode, ) -> Result<Self, AutomergeError>
load_with_options
insteadpub fn load_with_options( data: &[u8], options: LoadOptions<'_>, ) -> Result<Self, AutomergeError>
Sourcepub fn reset_diff_cursor(&mut self)
pub fn reset_diff_cursor(&mut self)
Erases the diff cursor created by Self::update_diff_cursor()
and no
longer indexes changes to the document.
Sourcepub fn update_diff_cursor(&mut self)
pub fn update_diff_cursor(&mut self)
Sets the Self::diff_cursor()
to current heads of the document and will begin
building an index with every change moving forward.
If Self::diff()
is called with Self::diff_cursor()
as before
and
Self::get_heads
() as after
- the index will be used
If the cursor is no longer needed it can be reset with
Self::reset_diff_cursor()
Sourcepub fn diff_cursor(&self) -> Vec<ChangeHash>
pub fn diff_cursor(&self) -> Vec<ChangeHash>
Returns the cursor set by Self::update_diff_cursor()
Sourcepub fn make_patches(&self, patch_log: &mut PatchLog) -> Vec<Patch>
pub fn make_patches(&self, patch_log: &mut PatchLog) -> Vec<Patch>
Generate the patches recorded in patch_log
Sourcepub fn diff(
&mut self,
before: &[ChangeHash],
after: &[ChangeHash],
) -> Vec<Patch>
pub fn diff( &mut self, before: &[ChangeHash], after: &[ChangeHash], ) -> Vec<Patch>
Generates a diff from before
to after
By default the diff requires a sequental scan of all the ops in the doc.
To do a fast indexed diff before
must equal Self::diff_cursor()
and
after
must equal Self::get_heads()
. The diff cursor is managed with
Self::update_diff_cursor()
and Self::reset_diff_cursor()
Managing the diff index has a small but non-zero overhead. It should be disabled if no longer needed. If a signifigantly large change is applied to the document it may be faster to reset the index before applying it, doing an unindxed diff afterwards and then reenable the index.
§Arguments
before
- heads fromSelf::get_heads()
at beginning point in the documents historyafter
- heads fromSelf::get_heads()
at ending point in the documents history.
Note: before
and after
do not have to be chronological. Document state can move backward.
Normal use might look like:
§Example
use automerge::{ AutoCommit };
let mut doc = AutoCommit::new(); // or AutoCommit::load(data)
// make some changes - use and update the index
let heads = doc.get_heads();
let diff_cursor = doc.diff_cursor();
let patches = doc.diff(&diff_cursor, &heads);
doc.update_diff_cursor();
See Self::diff_incremental()
for encapsulating this pattern.
Sourcepub fn diff_incremental(&mut self) -> Vec<Patch>
pub fn diff_incremental(&mut self) -> Vec<Patch>
This is a convience function that encapsulates the following common pattern
use automerge::AutoCommit;
let mut doc = AutoCommit::new();
// make some changes
let heads = doc.get_heads();
let diff_cursor = doc.diff_cursor();
let patches = doc.diff(&diff_cursor, &heads);
doc.update_diff_cursor();
pub fn fork(&mut self) -> Self
pub fn fork_at(&mut self, heads: &[ChangeHash]) -> Result<Self, AutomergeError>
pub fn with_actor(self, actor: ActorId) -> Self
pub fn set_actor(&mut self, actor: ActorId) -> &mut Self
pub fn get_actor(&self) -> &ActorId
pub fn isolate(&mut self, heads: &[ChangeHash])
pub fn integrate(&mut self)
Sourcepub fn load_incremental(&mut self, data: &[u8]) -> Result<usize, AutomergeError>
pub fn load_incremental(&mut self, data: &[u8]) -> Result<usize, AutomergeError>
Load an incremental save of a document.
Unlike Self::load()
this imports changes into an existing document. It will work with both
the output of Self::save()
and Self::save_incremental()
The return value is the number of ops which were applied, this is not useful and will change in future.
pub fn apply_changes( &mut self, changes: impl IntoIterator<Item = Change>, ) -> Result<(), AutomergeError>
Sourcepub fn merge(
&mut self,
other: &mut AutoCommit,
) -> Result<Vec<ChangeHash>, AutomergeError>
pub fn merge( &mut self, other: &mut AutoCommit, ) -> Result<Vec<ChangeHash>, AutomergeError>
Takes all the changes in other
which are not in self
and applies them
pub fn save_with_options(&mut self, options: SaveOptions) -> Vec<u8> ⓘ
Sourcepub fn save_and_verify(&mut self) -> Result<Vec<u8>, AutomergeError>
pub fn save_and_verify(&mut self) -> Result<Vec<u8>, AutomergeError>
Save the document and attempt to load it before returning - slow!
Sourcepub fn save_nocompress(&mut self) -> Vec<u8> ⓘ
pub fn save_nocompress(&mut self) -> Vec<u8> ⓘ
Save this document, but don’t run it through DEFLATE afterwards
Sourcepub fn save_incremental(&mut self) -> Vec<u8> ⓘ
pub fn save_incremental(&mut self) -> Vec<u8> ⓘ
Save the changes since the last call to Self::save()
The output of this will not be a compressed document format, but a series of individual
changes. This is useful if you know you have only made a small change since the last Self::save()
and you want to immediately send it somewhere (e.g. you’ve inserted a single character in a
text object).
Sourcepub fn save_after(&mut self, heads: &[ChangeHash]) -> Vec<u8> ⓘ
pub fn save_after(&mut self, heads: &[ChangeHash]) -> Vec<u8> ⓘ
Save everything which is not a (transitive) dependency of heads
pub fn get_missing_deps(&mut self, heads: &[ChangeHash]) -> Vec<ChangeHash>
Sourcepub fn get_last_local_change(&mut self) -> Option<&Change>
pub fn get_last_local_change(&mut self) -> Option<&Change>
Get the last change made by this documents actor ID
pub fn get_changes(&mut self, have_deps: &[ChangeHash]) -> Vec<&Change>
pub fn get_change_by_hash(&mut self, hash: &ChangeHash) -> Option<&Change>
Sourcepub fn get_changes_added<'a>(&mut self, other: &'a mut Self) -> Vec<&'a Change>
pub fn get_changes_added<'a>(&mut self, other: &'a mut Self) -> Vec<&'a Change>
Get changes in other
that are not in self
Sourcepub fn get_heads(&mut self) -> Vec<ChangeHash>
pub fn get_heads(&mut self) -> Vec<ChangeHash>
Get the current heads of the document.
This closes the transaction first, if one is in progress.
pub fn set_text_rep(&mut self, text_rep: TextRepresentation)
pub fn get_text_rep(&mut self) -> TextRepresentation
pub fn with_text_rep(self, text_rep: TextRepresentation) -> Self
Sourcepub fn commit(&mut self) -> Option<ChangeHash>
pub fn commit(&mut self) -> Option<ChangeHash>
Commit any uncommitted changes
Returns None
if there were no operations to commit
Sourcepub fn commit_with(&mut self, options: CommitOptions) -> Option<ChangeHash>
pub fn commit_with(&mut self, options: CommitOptions) -> Option<ChangeHash>
Commit the current operations with some options.
Returns None
if there were no operations to commit
let mut doc = AutoCommit::new();
doc.put_object(&ROOT, "todos", ObjType::List).unwrap();
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as
i64;
doc.commit_with(CommitOptions::default().with_message("Create todos list").with_time(now));
Sourcepub fn rollback(&mut self) -> usize
pub fn rollback(&mut self) -> usize
Remove any changes that have been made in the current transaction from the document
Sourcepub fn empty_change(&mut self, options: CommitOptions) -> ChangeHash
pub fn empty_change(&mut self, options: CommitOptions) -> ChangeHash
Generate an empty change
The main reason to do this is if you wish to create a “merge commit” which has all the current heads of the documents as dependencies but you have no new operations to create.
Because this structure is an “autocommit” there may actually be outstanding operations to
submit. If this is the case this function will create two changes, one with the outstanding
operations and a new one with no operations. The returned ChangeHash
will always be the
hash of the empty change.
Sourcepub fn sync(&mut self) -> impl SyncDoc + '_
pub fn sync(&mut self) -> impl SyncDoc + '_
An implementation of crate::sync::SyncDoc
for this autocommit
This ensures that any outstanding transactions for this document are committed before taking part in the sync protocol
Sourcepub fn hash_for_opid(&self, opid: &ExId) -> Option<ChangeHash>
pub fn hash_for_opid(&self, opid: &ExId) -> Option<ChangeHash>
Get the hash of the change that contains the given opid
.
Returns None
if the opid
:
- Is the root object id
- Does not exist in this document
- Is for an operation in a transaction
Sourcepub fn has_our_changes(&mut self, state: &State) -> bool
pub fn has_our_changes(&mut self, state: &State) -> bool
Whether the peer represented by other
has all the changes we have
Trait Implementations§
Source§impl Clone for AutoCommit
impl Clone for AutoCommit
Source§fn clone(&self) -> AutoCommit
fn clone(&self) -> AutoCommit
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for AutoCommit
impl Debug for AutoCommit
Source§impl Default for AutoCommit
An autocommit document with an inactive PatchLog
impl Default for AutoCommit
An autocommit document with an inactive PatchLog
See AutoCommit
Source§impl ReadDoc for AutoCommit
impl ReadDoc for AutoCommit
Source§fn parents<O: AsRef<ExId>>(&self, obj: O) -> Result<Parents<'_>, AutomergeError>
fn parents<O: AsRef<ExId>>(&self, obj: O) -> Result<Parents<'_>, AutomergeError>
Source§fn parents_at<O: AsRef<ExId>>(
&self,
obj: O,
heads: &[ChangeHash],
) -> Result<Parents<'_>, AutomergeError>
fn parents_at<O: AsRef<ExId>>( &self, obj: O, heads: &[ChangeHash], ) -> Result<Parents<'_>, AutomergeError>
Source§fn keys<O: AsRef<ExId>>(&self, obj: O) -> Keys<'_> ⓘ
fn keys<O: AsRef<ExId>>(&self, obj: O) -> Keys<'_> ⓘ
obj
. Read moreSource§fn map_range<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>(
&'a self,
obj: O,
range: R,
) -> MapRange<'a, R> ⓘ
fn map_range<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>( &'a self, obj: O, range: R, ) -> MapRange<'a, R> ⓘ
obj
in the given range. Read moreSource§fn map_range_at<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>(
&'a self,
obj: O,
range: R,
heads: &[ChangeHash],
) -> MapRange<'a, R> ⓘ
fn map_range_at<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>( &'a self, obj: O, range: R, heads: &[ChangeHash], ) -> MapRange<'a, R> ⓘ
Source§fn list_range<O: AsRef<ExId>, R: RangeBounds<usize>>(
&self,
obj: O,
range: R,
) -> ListRange<'_, R> ⓘ
fn list_range<O: AsRef<ExId>, R: RangeBounds<usize>>( &self, obj: O, range: R, ) -> ListRange<'_, R> ⓘ
obj
in the given range. Read moreSource§fn list_range_at<O: AsRef<ExId>, R: RangeBounds<usize>>(
&self,
obj: O,
range: R,
heads: &[ChangeHash],
) -> ListRange<'_, R> ⓘ
fn list_range_at<O: AsRef<ExId>, R: RangeBounds<usize>>( &self, obj: O, range: R, heads: &[ChangeHash], ) -> ListRange<'_, R> ⓘ
obj
in the given range as at heads
Read moreSource§fn values<O: AsRef<ExId>>(&self, obj: O) -> Values<'_> ⓘ
fn values<O: AsRef<ExId>>(&self, obj: O) -> Values<'_> ⓘ
Source§fn values_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> Values<'_> ⓘ
fn values_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> Values<'_> ⓘ
heads
Read moreSource§fn length<O: AsRef<ExId>>(&self, obj: O) -> usize
fn length<O: AsRef<ExId>>(&self, obj: O) -> usize
Source§fn length_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> usize
fn length_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> usize
heads
Read moreSource§fn object_type<O: AsRef<ExId>>(&self, obj: O) -> Result<ObjType, AutomergeError>
fn object_type<O: AsRef<ExId>>(&self, obj: O) -> Result<ObjType, AutomergeError>
Source§fn marks<O: AsRef<ExId>>(&self, obj: O) -> Result<Vec<Mark<'_>>, AutomergeError>
fn marks<O: AsRef<ExId>>(&self, obj: O) -> Result<Vec<Mark<'_>>, AutomergeError>
Source§fn marks_at<O: AsRef<ExId>>(
&self,
obj: O,
heads: &[ChangeHash],
) -> Result<Vec<Mark<'_>>, AutomergeError>
fn marks_at<O: AsRef<ExId>>( &self, obj: O, heads: &[ChangeHash], ) -> Result<Vec<Mark<'_>>, AutomergeError>
fn get_marks<O: AsRef<ExId>>( &self, obj: O, index: usize, heads: Option<&[ChangeHash]>, ) -> Result<MarkSet, AutomergeError>
Source§fn text<O: AsRef<ExId>>(&self, obj: O) -> Result<String, AutomergeError>
fn text<O: AsRef<ExId>>(&self, obj: O) -> Result<String, AutomergeError>
Source§fn text_at<O: AsRef<ExId>>(
&self,
obj: O,
heads: &[ChangeHash],
) -> Result<String, AutomergeError>
fn text_at<O: AsRef<ExId>>( &self, obj: O, heads: &[ChangeHash], ) -> Result<String, AutomergeError>
heads
, see
Self::text()
Source§fn spans<O: AsRef<ExId>>(&self, obj: O) -> Result<Spans<'_>, AutomergeError>
fn spans<O: AsRef<ExId>>(&self, obj: O) -> Result<Spans<'_>, AutomergeError>
obj
Source§fn spans_at<O: AsRef<ExId>>(
&self,
obj: O,
heads: &[ChangeHash],
) -> Result<Spans<'_>, AutomergeError>
fn spans_at<O: AsRef<ExId>>( &self, obj: O, heads: &[ChangeHash], ) -> Result<Spans<'_>, AutomergeError>
obj
as at heads
Source§fn get_cursor<O: AsRef<ExId>, I: Into<CursorPosition>>(
&self,
obj: O,
position: I,
at: Option<&[ChangeHash]>,
) -> Result<Cursor, AutomergeError>
fn get_cursor<O: AsRef<ExId>, I: Into<CursorPosition>>( &self, obj: O, position: I, at: Option<&[ChangeHash]>, ) -> Result<Cursor, AutomergeError>
usize
position in a Sequence (either ObjType::List
or ObjType::Text
). Read moreSource§fn get_cursor_moving<O: AsRef<ExId>, I: Into<CursorPosition>>(
&self,
obj: O,
position: I,
at: Option<&[ChangeHash]>,
move_cursor: MoveCursor,
) -> Result<Cursor, AutomergeError>
fn get_cursor_moving<O: AsRef<ExId>, I: Into<CursorPosition>>( &self, obj: O, position: I, at: Option<&[ChangeHash]>, move_cursor: MoveCursor, ) -> Result<Cursor, AutomergeError>
usize
position in a Sequence (either ObjType::List
or ObjType::Text
). Read moreSource§fn get_cursor_position<O: AsRef<ExId>>(
&self,
obj: O,
cursor: &Cursor,
at: Option<&[ChangeHash]>,
) -> Result<usize, AutomergeError>
fn get_cursor_position<O: AsRef<ExId>>( &self, obj: O, cursor: &Cursor, at: Option<&[ChangeHash]>, ) -> Result<usize, AutomergeError>
fn hydrate<O: AsRef<ExId>>( &self, obj: O, heads: Option<&[ChangeHash]>, ) -> Result<Value, AutomergeError>
Source§fn get<O: AsRef<ExId>, P: Into<Prop>>(
&self,
obj: O,
prop: P,
) -> Result<Option<(Value<'_>, ExId)>, AutomergeError>
fn get<O: AsRef<ExId>, P: Into<Prop>>( &self, obj: O, prop: P, ) -> Result<Option<(Value<'_>, ExId)>, AutomergeError>
Source§fn get_at<O: AsRef<ExId>, P: Into<Prop>>(
&self,
obj: O,
prop: P,
heads: &[ChangeHash],
) -> Result<Option<(Value<'_>, ExId)>, AutomergeError>
fn get_at<O: AsRef<ExId>, P: Into<Prop>>( &self, obj: O, prop: P, heads: &[ChangeHash], ) -> Result<Option<(Value<'_>, ExId)>, AutomergeError>
heads
, see Self::get()
Source§fn get_all<O: AsRef<ExId>, P: Into<Prop>>(
&self,
obj: O,
prop: P,
) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError>
fn get_all<O: AsRef<ExId>, P: Into<Prop>>( &self, obj: O, prop: P, ) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError>
Source§fn get_all_at<O: AsRef<ExId>, P: Into<Prop>>(
&self,
obj: O,
prop: P,
heads: &[ChangeHash],
) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError>
fn get_all_at<O: AsRef<ExId>, P: Into<Prop>>( &self, obj: O, prop: P, heads: &[ChangeHash], ) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError>
heads
Read moreSource§fn get_missing_deps(&self, heads: &[ChangeHash]) -> Vec<ChangeHash>
fn get_missing_deps(&self, heads: &[ChangeHash]) -> Vec<ChangeHash>
heads
.Source§fn get_change_by_hash(&self, hash: &ChangeHash) -> Option<&Change>
fn get_change_by_hash(&self, hash: &ChangeHash) -> Option<&Change>
fn text_encoding(&self) -> TextEncoding
Source§impl Transactable for AutoCommit
impl Transactable for AutoCommit
Source§fn splice<O: AsRef<ExId>, V: IntoIterator<Item = ScalarValue>>(
&mut self,
obj: O,
pos: usize,
del: isize,
vals: V,
) -> Result<(), AutomergeError>
fn splice<O: AsRef<ExId>, V: IntoIterator<Item = ScalarValue>>( &mut self, obj: O, pos: usize, del: isize, vals: V, ) -> Result<(), AutomergeError>
Splice new elements into the given sequence. Returns a vector of the OpIds used to insert the new elements
Source§fn pending_ops(&self) -> usize
fn pending_ops(&self) -> usize
Source§fn put<O: AsRef<ExId>, P: Into<Prop>, V: Into<ScalarValue>>(
&mut self,
obj: O,
prop: P,
value: V,
) -> Result<(), AutomergeError>
fn put<O: AsRef<ExId>, P: Into<Prop>, V: Into<ScalarValue>>( &mut self, obj: O, prop: P, value: V, ) -> Result<(), AutomergeError>
Source§fn put_object<O: AsRef<ExId>, P: Into<Prop>>(
&mut self,
obj: O,
prop: P,
value: ObjType,
) -> Result<ExId, AutomergeError>
fn put_object<O: AsRef<ExId>, P: Into<Prop>>( &mut self, obj: O, prop: P, value: ObjType, ) -> Result<ExId, AutomergeError>
Source§fn insert<O: AsRef<ExId>, V: Into<ScalarValue>>(
&mut self,
obj: O,
index: usize,
value: V,
) -> Result<(), AutomergeError>
fn insert<O: AsRef<ExId>, V: Into<ScalarValue>>( &mut self, obj: O, index: usize, value: V, ) -> Result<(), AutomergeError>
Source§fn insert_object<O: AsRef<ExId>>(
&mut self,
obj: O,
index: usize,
value: ObjType,
) -> Result<ExId, AutomergeError>
fn insert_object<O: AsRef<ExId>>( &mut self, obj: O, index: usize, value: ObjType, ) -> Result<ExId, AutomergeError>
Source§fn increment<O: AsRef<ExId>, P: Into<Prop>>(
&mut self,
obj: O,
prop: P,
value: i64,
) -> Result<(), AutomergeError>
fn increment<O: AsRef<ExId>, P: Into<Prop>>( &mut self, obj: O, prop: P, value: i64, ) -> Result<(), AutomergeError>
value
.Source§fn delete<O: AsRef<ExId>, P: Into<Prop>>(
&mut self,
obj: O,
prop: P,
) -> Result<(), AutomergeError>
fn delete<O: AsRef<ExId>, P: Into<Prop>>( &mut self, obj: O, prop: P, ) -> Result<(), AutomergeError>
Source§fn splice_text<O: AsRef<ExId>>(
&mut self,
obj: O,
pos: usize,
del: isize,
text: &str,
) -> Result<(), AutomergeError>
fn splice_text<O: AsRef<ExId>>( &mut self, obj: O, pos: usize, del: isize, text: &str, ) -> Result<(), AutomergeError>
Self::splice
but for text.Source§fn mark<O: AsRef<ExId>>(
&mut self,
obj: O,
mark: Mark<'_>,
expand: ExpandMark,
) -> Result<(), AutomergeError>
fn mark<O: AsRef<ExId>>( &mut self, obj: O, mark: Mark<'_>, expand: ExpandMark, ) -> Result<(), AutomergeError>
Source§fn unmark<O: AsRef<ExId>>(
&mut self,
obj: O,
key: &str,
start: usize,
end: usize,
expand: ExpandMark,
) -> Result<(), AutomergeError>
fn unmark<O: AsRef<ExId>>( &mut self, obj: O, key: &str, start: usize, end: usize, expand: ExpandMark, ) -> Result<(), AutomergeError>
Source§fn split_block<'p, O>(
&mut self,
obj: O,
index: usize,
) -> Result<ExId, AutomergeError>
fn split_block<'p, O>( &mut self, obj: O, index: usize, ) -> Result<ExId, AutomergeError>
obj
at the given index. Read moreSource§fn join_block<O: AsRef<ExId>>(
&mut self,
text: O,
index: usize,
) -> Result<(), AutomergeError>
fn join_block<O: AsRef<ExId>>( &mut self, text: O, index: usize, ) -> Result<(), AutomergeError>
index
from the text object obj
.Source§fn replace_block<'p, O>(
&mut self,
text: O,
index: usize,
) -> Result<ExId, AutomergeError>
fn replace_block<'p, O>( &mut self, text: O, index: usize, ) -> Result<ExId, AutomergeError>
index
in obj
with a new marker and return the ID of the new
marker