Struct Tree

Source
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

Source

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?
examples/sync.rs (line 10)
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
Hide additional examples
examples/basic.rs (line 7)
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}
examples/sync_reconcile.rs (line 10)
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}
Source

pub fn is_poisoned(&self) -> bool

Returns true if the tree is poisoned.

Source

pub fn get_poisoned_reason(&self) -> Option<TreeError>

Returns the reason the tree is poisoned, if it is poisoned.

Source

pub fn root(self: &Arc<Self>) -> Arc<Node>

Returns the root node of the tree.

Source

pub fn has_node(self: &Arc<Self>, id: impl Into<NodeId>) -> bool

Returns true if the tree has a node with the given ID.

Source

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?
examples/sync_reconcile.rs (line 24)
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}
Source

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?
examples/basic.rs (lines 9-16)
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 Clone for Tree

Source§

fn clone(&self) -> Tree

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Tree

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Tree

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl NodeApi for Tree

Tree implements NodeApi, forwarding the calls to the root node of the tree

Source§

fn id(self: &Arc<Self>) -> &NodeId

Returns the ID of the node.
Source§

fn create_child(self: &Arc<Self>) -> Result<Arc<Node>>

Creates a new child node with a generated ID.
Source§

fn create_child_at(self: &Arc<Self>, index: usize) -> Result<Arc<Node>>

Creates a new child node with a generated ID at the given index in the parent’s children.
Source§

fn create_child_with_id( self: &Arc<Self>, id: impl Into<NodeId>, ) -> Result<Arc<Node>>

Creates a new child node with the given ID at the end of the parent’s children.
Source§

fn create_child_with_id_at( self: &Arc<Self>, id: impl Into<NodeId>, index: usize, ) -> Result<Arc<Node>>

Creates a new child node with the given ID at the given index in the parent’s children.
Source§

fn move_to( self: &Arc<Self>, _parent: &Node, _index: Option<usize>, ) -> Result<()>

Moves the node to the given parent, placing it in that parent’s children at the given index. Read more
Source§

fn move_before(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>

Moves the node before the given node. Read more
Source§

fn move_after(self: &Arc<Self>, _other: &Arc<Node>) -> Result<()>

Moves the node after the given node. Read more
Source§

fn children(self: &Arc<Self>) -> Vec<Arc<Node>>

Returns the children of the node.
Source§

fn parent(self: &Arc<Self>) -> Option<Arc<Node>>

Returns the parent of the node.
Source§

fn ancestors(self: &Arc<Self>) -> Vec<Arc<Node>>

Returns the ancestors of the node, starting with the node’s parent and ending at the root node.
Source§

fn descendants(self: &Arc<Self>, order: TraversalOrder) -> Vec<Arc<Node>>

Returns the descendants of the node. Equivalent to self.traverse(order).skip(1).collect().
Source§

fn siblings(self: &Arc<Self>) -> Vec<Arc<Node>>

Returns the siblings of the node.
Source§

fn depth(self: &Arc<Self>) -> usize

Returns the depth of the node. The root node has a depth of 0; all other nodes have a depth of 1 plus the depth of their parent.
Source§

fn delete(self: &Arc<Self>, strategy: DeleteStrategy) -> Result<()>

Deletes the node from the tree. Read more
Source§

fn traverse(self: &Arc<Self>, order: TraversalOrder) -> TreeIter

Returns an iterator over the node and its descendants in the given order.
Source§

impl PartialEq for Tree

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl !Freeze for Tree

§

impl !RefUnwindSafe for Tree

§

impl !Send for Tree

§

impl !Sync for Tree

§

impl Unpin for Tree

§

impl !UnwindSafe for Tree

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.