The Rust API has so far grown somewhat organically driven by the needs of the javascript implementation. This has led to an API which is quite awkward and unfamiliar to Rust programmers. Additionally there is no documentation to speak of. This commit is the first movement towards cleaning things up a bit. We touch a lot of files but the changes are all very mechanical. We introduce a few traits to abstract over the common operations between `Automerge` and `AutoCommit`, and add a whole bunch of documentation. * Add a `ReadDoc` trait to describe methods which read value from a document. make `Transactable` extend `ReadDoc` * Add a `SyncDoc` trait to describe methods necessary for synchronizing documents. * Put the `SyncDoc` implementation for `AutoCommit` behind `AutoCommit::sync` to ensure that any open transactions are closed before taking part in the sync protocol * Split `OpObserver` into two traits: `OpObserver` + `BranchableObserver`. `BranchableObserver` captures the methods which are only needed for observing transactions. * Add a whole bunch of documentation. The main changes Rust users will need to make is: * Import the `ReadDoc` trait wherever you are using the methods which have been moved to it. Optionally change concrete paramters on functions to `ReadDoc` constraints. * Likewise import the `SyncDoc` trait wherever you are doing synchronisation work * If you are using the `AutoCommit::*_sync_message` methods you will need to add a call to `AutoCommit::sync()` first. E.g. `doc.generate_sync_message` becomes `doc.sync().generate_sync_message` * If you have an implementation of `OpObserver` which you are using in an `AutoCommit` then split it into an implementation of `OpObserver` and `BranchableObserver`
93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
use crate::exid::ExId;
|
|
use crate::{AutomergeError, ChangeHash, ObjType, Prop, ReadDoc, ScalarValue};
|
|
|
|
/// A way of mutating a document within a single change.
|
|
pub trait Transactable: ReadDoc {
|
|
/// Get the number of pending operations in this transaction.
|
|
fn pending_ops(&self) -> usize;
|
|
|
|
/// Set the value of property `P` to value `V` in object `obj`.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This will return an error if
|
|
/// - The object does not exist
|
|
/// - The key is the wrong type for the object
|
|
/// - The key does not exist in the object
|
|
fn put<O: AsRef<ExId>, P: Into<Prop>, V: Into<ScalarValue>>(
|
|
&mut self,
|
|
obj: O,
|
|
prop: P,
|
|
value: V,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
/// Set the value of property `P` to the new object `V` in object `obj`.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// The id of the object which was created.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This will return an error if
|
|
/// - The object does not exist
|
|
/// - The key is the wrong type for the object
|
|
/// - The key does not exist in the object
|
|
fn put_object<O: AsRef<ExId>, P: Into<Prop>>(
|
|
&mut self,
|
|
obj: O,
|
|
prop: P,
|
|
object: ObjType,
|
|
) -> Result<ExId, AutomergeError>;
|
|
|
|
/// Insert a value into a list at the given index.
|
|
fn insert<O: AsRef<ExId>, V: Into<ScalarValue>>(
|
|
&mut self,
|
|
obj: O,
|
|
index: usize,
|
|
value: V,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
/// Insert an object into a list at the given index.
|
|
fn insert_object<O: AsRef<ExId>>(
|
|
&mut self,
|
|
obj: O,
|
|
index: usize,
|
|
object: ObjType,
|
|
) -> Result<ExId, AutomergeError>;
|
|
|
|
/// Increment the counter at the prop in the object by `value`.
|
|
fn increment<O: AsRef<ExId>, P: Into<Prop>>(
|
|
&mut self,
|
|
obj: O,
|
|
prop: P,
|
|
value: i64,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
/// Delete the value at prop in the object.
|
|
fn delete<O: AsRef<ExId>, P: Into<Prop>>(
|
|
&mut self,
|
|
obj: O,
|
|
prop: P,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
fn splice<O: AsRef<ExId>, V: IntoIterator<Item = ScalarValue>>(
|
|
&mut self,
|
|
obj: O,
|
|
pos: usize,
|
|
del: usize,
|
|
vals: V,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
/// Like [`Self::splice`] but for text.
|
|
fn splice_text<O: AsRef<ExId>>(
|
|
&mut self,
|
|
obj: O,
|
|
pos: usize,
|
|
del: usize,
|
|
text: &str,
|
|
) -> Result<(), AutomergeError>;
|
|
|
|
/// The heads this transaction will be based on
|
|
fn base_heads(&self) -> Vec<ChangeHash>;
|
|
}
|