pub struct Tree { /* private fields */ }
Expand description
A tree CRDT backed by a Yrs document.
Tree
implements NodeApi
, forwarding the calls to the root node of the tree,
allowing you to add nodes to the root node without calling root()
.
§Tree Poisoning
When the underlying Yrs document is updated, the tree automatically updates its state in response. If the library detects that the Yrs document is malformed in a way that cannot be reconciled, it will mark the tree as “poisoned.”
Once a tree is poisoned, any operations on the tree that rely on the Yrs document will
fail with a TreePoisoned
error. Operations that only rely on the tree’s cached state
will continue to succeed, but will not reflect the latest state of the Yrs document.
You can receive a notification when a tree is poisoned by subscribing to the tree’s
events via Tree::on_change
.
Implementations§
Source§impl Tree
impl Tree
Sourcepub fn new(doc: Arc<Doc>, tree_name: &str) -> Result<Arc<Self>>
pub fn new(doc: Arc<Doc>, tree_name: &str) -> Result<Arc<Self>>
Creates a new tree in the Yjs doc with the given container name. The tree will take over the map at the given name in the Yrs doc, and it should not be modified manually after creation.
Examples found in repository?
6fn main() -> Result<(), Box<dyn Error>> {
7 let doc1 = Arc::new(yrs::Doc::new());
8 let doc2 = Arc::new(yrs::Doc::new());
9
10 let tree1 = Tree::new(doc1.clone(), "test")?;
11 let tree2 = Tree::new(doc2.clone(), "test")?;
12
13 let node1 = tree1.create_child_with_id("1")?;
14 let node2 = tree1.create_child_with_id("2")?;
15 let node3 = node1.create_child_with_id("3")?;
16 let node4 = node2.create_child_with_id("4")?;
17 node3.move_to(&node2, Some(0))?;
18 node1.move_after(&node2)?;
19 node4.move_before(&node3)?;
20
21 println!("Tree 1: \n{}", tree1);
22 println!("Syncing Yjs documents...\n");
23
24 let txn = doc1.transact();
25 let update = txn.encode_state_as_update_v1(&Default::default());
26 drop(txn);
27
28 doc2.transact_mut()
29 .apply_update(Update::decode_v1(&update).unwrap())?;
30
31 println!("Tree 2: \n{}", tree2);
32
33 Ok(())
34}
More examples
5fn main() -> Result<(), Box<dyn Error>> {
6 let doc = Arc::new(yrs::Doc::new());
7 let tree = Tree::new(doc.clone(), "test")?;
8
9 let _sub = tree.on_change(|e| match e {
10 TreeEvent::TreeUpdated(tree) => {
11 println!("{}", tree);
12 }
13 TreeEvent::TreePoisoned(_tree, err) => {
14 println!("Tree is poisoned: {}", err);
15 }
16 });
17
18 println!("Add 1 to ROOT");
19 let node1 = tree.create_child_with_id("1")?;
20 println!("Add 2 to ROOT");
21 let node2 = tree.create_child_with_id("2")?;
22 println!("Add 3 to 1");
23 let node3 = node1.create_child_with_id("3")?;
24 println!("Add 4 to 2");
25 let node4 = node2.create_child_with_id("4")?;
26
27 println!("Move 3 to 2, index 0");
28 node3.move_to(&node2, Some(0))?;
29
30 println!("Move 1 after 2");
31 node1.move_after(&node2)?;
32
33 println!("Move 4 before 3");
34 node4.move_before(&node3)?;
35
36 println!("Set data on 1: my_key = my_value");
37 node1.set("my_key", "my_value")?;
38
39 let val = node1.get_as::<String>("my_key")?;
40 println!("Get data from 1: my_key = {}", val);
41
42 Ok(())
43}
6fn main() -> Result<(), Box<dyn Error>> {
7 let doc1 = Arc::new(yrs::Doc::new());
8 let doc2 = Arc::new(yrs::Doc::new());
9
10 let tree1 = Tree::new(doc1.clone(), "test")?;
11 let tree2 = Tree::new(doc2.clone(), "test")?;
12
13 let node1 = tree1.create_child_with_id("1")?;
14 let node2 = tree1.create_child_with_id("2")?;
15 let node3 = node1.create_child_with_id("3")?;
16 let node4 = node2.create_child_with_id("4")?;
17 node3.move_to(&node2, Some(0))?;
18 node1.move_after(&node2)?;
19 node4.move_before(&node3)?;
20
21 sync_docs(&doc1, &doc2)?;
22
23 // Simulate a cycle created by disparate clients
24 let node3_left = tree1.get_node("3").unwrap();
25 let node4_left = tree1.get_node("4").unwrap();
26 node3_left.move_to(&node4_left, None)?;
27
28 let node3_right = tree2.get_node("3").unwrap();
29 let node4_right = tree2.get_node("4").unwrap();
30 node4_right.move_to(&node3_right, None)?;
31
32 println!("Tree 1: \n{}", tree1);
33 println!("Tree 2: \n{}", tree2);
34
35 println!("Syncing docs...\n");
36 sync_docs(&doc1, &doc2)?;
37
38 println!("Tree 1: \n{}", tree1);
39 println!("Tree 2: \n{}", tree2);
40
41 Ok(())
42}
Sourcepub fn is_poisoned(&self) -> bool
pub fn is_poisoned(&self) -> bool
Returns true if the tree is poisoned.
Sourcepub fn get_poisoned_reason(&self) -> Option<TreeError>
pub fn get_poisoned_reason(&self) -> Option<TreeError>
Returns the reason the tree is poisoned, if it is poisoned.
Sourcepub fn has_node(self: &Arc<Self>, id: impl Into<NodeId>) -> bool
pub fn has_node(self: &Arc<Self>, id: impl Into<NodeId>) -> bool
Returns true if the tree has a node with the given ID.
Sourcepub fn get_node(self: &Arc<Self>, id: impl Into<NodeId>) -> Option<Arc<Node>>
pub fn get_node(self: &Arc<Self>, id: impl Into<NodeId>) -> Option<Arc<Node>>
Returns the node with the given ID.
Examples found in repository?
6fn main() -> Result<(), Box<dyn Error>> {
7 let doc1 = Arc::new(yrs::Doc::new());
8 let doc2 = Arc::new(yrs::Doc::new());
9
10 let tree1 = Tree::new(doc1.clone(), "test")?;
11 let tree2 = Tree::new(doc2.clone(), "test")?;
12
13 let node1 = tree1.create_child_with_id("1")?;
14 let node2 = tree1.create_child_with_id("2")?;
15 let node3 = node1.create_child_with_id("3")?;
16 let node4 = node2.create_child_with_id("4")?;
17 node3.move_to(&node2, Some(0))?;
18 node1.move_after(&node2)?;
19 node4.move_before(&node3)?;
20
21 sync_docs(&doc1, &doc2)?;
22
23 // Simulate a cycle created by disparate clients
24 let node3_left = tree1.get_node("3").unwrap();
25 let node4_left = tree1.get_node("4").unwrap();
26 node3_left.move_to(&node4_left, None)?;
27
28 let node3_right = tree2.get_node("3").unwrap();
29 let node4_right = tree2.get_node("4").unwrap();
30 node4_right.move_to(&node3_right, None)?;
31
32 println!("Tree 1: \n{}", tree1);
33 println!("Tree 2: \n{}", tree2);
34
35 println!("Syncing docs...\n");
36 sync_docs(&doc1, &doc2)?;
37
38 println!("Tree 1: \n{}", tree1);
39 println!("Tree 2: \n{}", tree2);
40
41 Ok(())
42}
Sourcepub fn on_change(
&self,
callback: impl Fn(&TreeEvent) + Send + Sync + 'static,
) -> Subscription
pub fn on_change( &self, callback: impl Fn(&TreeEvent) + Send + Sync + 'static, ) -> Subscription
Returns a subscription to the tree’s events. When dropped, the subscription is automatically cancelled.
Examples found in repository?
5fn main() -> Result<(), Box<dyn Error>> {
6 let doc = Arc::new(yrs::Doc::new());
7 let tree = Tree::new(doc.clone(), "test")?;
8
9 let _sub = tree.on_change(|e| match e {
10 TreeEvent::TreeUpdated(tree) => {
11 println!("{}", tree);
12 }
13 TreeEvent::TreePoisoned(_tree, err) => {
14 println!("Tree is poisoned: {}", err);
15 }
16 });
17
18 println!("Add 1 to ROOT");
19 let node1 = tree.create_child_with_id("1")?;
20 println!("Add 2 to ROOT");
21 let node2 = tree.create_child_with_id("2")?;
22 println!("Add 3 to 1");
23 let node3 = node1.create_child_with_id("3")?;
24 println!("Add 4 to 2");
25 let node4 = node2.create_child_with_id("4")?;
26
27 println!("Move 3 to 2, index 0");
28 node3.move_to(&node2, Some(0))?;
29
30 println!("Move 1 after 2");
31 node1.move_after(&node2)?;
32
33 println!("Move 4 before 3");
34 node4.move_before(&node3)?;
35
36 println!("Set data on 1: my_key = my_value");
37 node1.set("my_key", "my_value")?;
38
39 let val = node1.get_as::<String>("my_key")?;
40 println!("Get data from 1: my_key = {}", val);
41
42 Ok(())
43}
Trait Implementations§
Source§impl NodeApi for Tree
Tree
implements NodeApi
, forwarding the calls to the root node of the tree
impl NodeApi for Tree
Tree
implements NodeApi
, forwarding the calls to the root node of the tree
Source§fn create_child(self: &Arc<Self>) -> Result<Arc<Node>>
fn create_child(self: &Arc<Self>) -> Result<Arc<Node>>
Source§fn create_child_at(self: &Arc<Self>, index: usize) -> Result<Arc<Node>>
fn create_child_at(self: &Arc<Self>, index: usize) -> Result<Arc<Node>>
Source§fn create_child_with_id(
self: &Arc<Self>,
id: impl Into<NodeId>,
) -> Result<Arc<Node>>
fn create_child_with_id( self: &Arc<Self>, id: impl Into<NodeId>, ) -> Result<Arc<Node>>
Source§fn create_child_with_id_at(
self: &Arc<Self>,
id: impl Into<NodeId>,
index: usize,
) -> Result<Arc<Node>>
fn create_child_with_id_at( self: &Arc<Self>, id: impl Into<NodeId>, index: usize, ) -> Result<Arc<Node>>
Source§fn move_to(
self: &Arc<Self>,
_parent: &Node,
_index: Option<usize>,
) -> Result<()>
fn move_to( self: &Arc<Self>, _parent: &Node, _index: Option<usize>, ) -> Result<()>
Source§fn move_before(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>
fn move_before(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>
Source§fn move_after(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>
fn move_after(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>
Source§fn ancestors(self: &Arc<Self>) -> Vec<Arc<Node>>
fn ancestors(self: &Arc<Self>) -> Vec<Arc<Node>>
Source§fn descendants(self: &Arc<Self>, order: TraversalOrder) -> Vec<Arc<Node>>
fn descendants(self: &Arc<Self>, order: TraversalOrder) -> Vec<Arc<Node>>
self.traverse(order).skip(1).collect()
.