Add lifetimes to transact_with and fixup watch example
This commit is contained in:
parent
b6fd7ac26e
commit
702a0ec172
4 changed files with 65 additions and 50 deletions
|
@ -442,7 +442,7 @@ impl Automerge {
|
|||
js_set(&patch, "conflict", conflict)?;
|
||||
}
|
||||
|
||||
Patch::Insert(obj, index, value) => {
|
||||
Patch::Insert { obj, index, value } => {
|
||||
js_set(&patch, "action", "insert")?;
|
||||
js_set(&patch, "obj", obj.to_string())?;
|
||||
js_set(&patch, "key", index as f64)?;
|
||||
|
@ -458,7 +458,7 @@ impl Automerge {
|
|||
};
|
||||
}
|
||||
|
||||
Patch::Delete(obj, key) => {
|
||||
Patch::Delete { obj, key } => {
|
||||
js_set(&patch, "action", "delete")?;
|
||||
js_set(&patch, "obj", obj.to_string())?;
|
||||
js_set(&patch, "key", key)?;
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
use automerge::transaction::CommitOptions;
|
||||
use automerge::transaction::Transactable;
|
||||
use automerge::Automerge;
|
||||
use automerge::ChangeHash;
|
||||
use automerge::ObjId;
|
||||
use automerge::AutomergeError;
|
||||
use automerge::Patch;
|
||||
use automerge::VecOpObserver;
|
||||
use automerge::ROOT;
|
||||
|
||||
fn main() {
|
||||
let mut doc = Automerge::new();
|
||||
let heads1 = doc.get_heads();
|
||||
|
||||
let mut observer = VecOpObserver::default();
|
||||
// a simple scalar change in the root object
|
||||
let mut tx = doc.transaction();
|
||||
tx.put(ROOT, "hello", "world").unwrap();
|
||||
let heads2 = tx.commit();
|
||||
get_changes(&heads1, &doc);
|
||||
doc.transact_with::<_, _, AutomergeError, _, _>(
|
||||
|_result| CommitOptions::default().with_op_observer(&mut observer),
|
||||
|tx| {
|
||||
tx.put(ROOT, "hello", "world").unwrap();
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
get_changes(&doc, observer.take_patches());
|
||||
|
||||
let mut tx = doc.transaction();
|
||||
let map = tx
|
||||
|
@ -23,47 +30,48 @@ fn main() {
|
|||
let list = tx
|
||||
.put_object(&map, "my list", automerge::ObjType::List)
|
||||
.unwrap();
|
||||
// tx.insert(&list, 0, "yay").unwrap();
|
||||
tx.insert(&list, 0, "yay").unwrap();
|
||||
let m = tx.insert_object(&list, 0, automerge::ObjType::Map).unwrap();
|
||||
tx.put(&m, "hi", 2).unwrap();
|
||||
tx.insert(&list, 1, "woo").unwrap();
|
||||
let m = tx.insert_object(&list, 2, automerge::ObjType::Map).unwrap();
|
||||
tx.put(&m, "hi", 2).unwrap();
|
||||
let _heads3 = tx.commit();
|
||||
get_changes(&[heads2], &doc);
|
||||
|
||||
// now if a peer were to send us a change that added a key in map we wouldn't know the path to
|
||||
// the change or we might not have a reference to the map objid.
|
||||
let _heads3 = tx.commit_with(CommitOptions::default().with_op_observer(&mut observer));
|
||||
get_changes(&doc, observer.take_patches());
|
||||
}
|
||||
|
||||
fn get_changes(heads: &[ChangeHash], doc: &Automerge) {
|
||||
let changes = doc.get_changes(heads);
|
||||
// changes should be in topological order
|
||||
for change in changes {
|
||||
let change = change.decode();
|
||||
for op in change.operations {
|
||||
// get the object that it changed
|
||||
let obj = doc.import(&op.obj.to_string()).unwrap();
|
||||
// get the prop too
|
||||
let prop = format!("{:?}", op.key);
|
||||
println!("{:?}", op);
|
||||
println!(
|
||||
"{} {:?} in obj {:?}, object path {:?}",
|
||||
if op.insert { "inserted" } else { "changed" },
|
||||
prop,
|
||||
fn get_changes(doc: &Automerge, patches: Vec<Patch>) {
|
||||
for patch in patches {
|
||||
match patch {
|
||||
Patch::Put {
|
||||
obj,
|
||||
get_path_for_obj(doc, &obj)
|
||||
);
|
||||
key,
|
||||
value,
|
||||
conflict: _,
|
||||
} => {
|
||||
println!(
|
||||
"put {:?} at {:?} in obj {:?}, object path {:?}",
|
||||
value,
|
||||
key,
|
||||
obj,
|
||||
doc.path_to_object(&obj)
|
||||
)
|
||||
}
|
||||
Patch::Insert { obj, index, value } => {
|
||||
println!(
|
||||
"insert {:?} at {:?} in obj {:?}, object path {:?}",
|
||||
value,
|
||||
index,
|
||||
obj,
|
||||
doc.path_to_object(&obj)
|
||||
)
|
||||
}
|
||||
Patch::Delete { obj, key } => println!(
|
||||
"delete {:?} in obj {:?}, object path {:?}",
|
||||
key,
|
||||
obj,
|
||||
doc.path_to_object(&obj)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path_for_obj(doc: &Automerge, obj: &ObjId) -> String {
|
||||
let mut s = String::new();
|
||||
let mut obj = obj.clone();
|
||||
while let Some((parent, key)) = doc.parent_object(obj) {
|
||||
s = format!("{}/{}", key, s);
|
||||
obj = parent;
|
||||
}
|
||||
s
|
||||
}
|
||||
|
|
|
@ -154,11 +154,11 @@ impl Automerge {
|
|||
}
|
||||
|
||||
/// Like [`Self::transact`] but with a function for generating the commit options.
|
||||
pub fn transact_with<F, O, E, C, Obs>(&mut self, c: C, f: F) -> transaction::Result<O, E>
|
||||
pub fn transact_with<'a, F, O, E, C, Obs>(&mut self, c: C, f: F) -> transaction::Result<O, E>
|
||||
where
|
||||
F: FnOnce(&mut Transaction) -> Result<O, E>,
|
||||
C: FnOnce(&O) -> CommitOptions<Obs>,
|
||||
Obs: OpObserver,
|
||||
C: FnOnce(&O) -> CommitOptions<'a, Obs>,
|
||||
Obs: 'a + OpObserver,
|
||||
{
|
||||
let mut tx = self.transaction();
|
||||
let result = f(&mut tx);
|
||||
|
|
|
@ -52,8 +52,11 @@ impl VecOpObserver {
|
|||
|
||||
impl OpObserver for VecOpObserver {
|
||||
fn insert(&mut self, obj_id: ExId, index: usize, (value, id): (Value, ExId)) {
|
||||
self.patches
|
||||
.push(Patch::Insert(obj_id, index, (value.into_owned(), id)));
|
||||
self.patches.push(Patch::Insert {
|
||||
obj: obj_id,
|
||||
index,
|
||||
value: (value.into_owned(), id),
|
||||
});
|
||||
}
|
||||
|
||||
fn put(&mut self, objid: ExId, key: Prop, (value, id): (Value, ExId), conflict: bool) {
|
||||
|
@ -66,7 +69,7 @@ impl OpObserver for VecOpObserver {
|
|||
}
|
||||
|
||||
fn delete(&mut self, objid: ExId, key: Prop) {
|
||||
self.patches.push(Patch::Delete(objid, key))
|
||||
self.patches.push(Patch::Delete { obj: objid, key })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +84,11 @@ pub enum Patch {
|
|||
conflict: bool,
|
||||
},
|
||||
/// Inserting a new element into a list/text
|
||||
Insert(ExId, usize, (Value<'static>, ExId)),
|
||||
Insert {
|
||||
obj: ExId,
|
||||
index: usize,
|
||||
value: (Value<'static>, ExId),
|
||||
},
|
||||
/// Deleting an element from a list/text
|
||||
Delete(ExId, Prop),
|
||||
Delete { obj: ExId, key: Prop },
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue