AtuinStand.Node (atuin_stand v0.1.0)
View SourceA node in an AtuinStand.Tree
.
You can access the node's ID via the id
property, and the tree it belongs to
via the tree
property.
Since Node
structs only hold a reference to their containing tree, nodes
might be invalidated if the tree is manipulated such that the node is removed.
In this case, the Node
functions will return {:error, :not_found}
.
For a more detailed overview of the API, see AtuinStand
.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
%AtuinStand.Node{id: :root, tree: tree}
iex> AtuinStand.Node.create_child(root, "node1")
%AtuinStand.Node{id: "node1", tree: tree}
Summary
Functions
Returns a list of all ancestors of the given node, starting at the node's parent and ending at the root node (inclusive).
Returns a list of all children of the given node.
Creates a new child node with the given ID.
Deletes the node from the tree.
Returns the depth of the given node.
Returns a list of all descendants of the given node.
Returns the user-defined data associated with the node.
Moves the node after the given node.
Moves the node before the given node.
Moves the node to a new parent node.
Returns the parent of the given node.
Moves the node to a new position amongst its siblings.
Sets the user-defined data associated with the node. Returns the node.
Returns a list of all siblings (other nodes with the same parent) of the given node.
Types
@type t() :: %AtuinStand.Node{id: atom() | String.t(), tree: AtuinStand.Tree.t()}
Functions
Returns a list of all ancestors of the given node, starting at the node's parent and ending at the root node (inclusive).
Returns {:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(node1, "node2")
iex> node3 = AtuinStand.Node.create_child(node2, "node3")
iex> AtuinStand.Node.ancestors(node3)
[node2, node1, root]
Returns a list of all children of the given node.
Returns {:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(root, "node2")
iex> AtuinStand.Node.children(root)
[node1, node2]
iex> AtuinStand.Node.children(node1)
[]
Creates a new child node with the given ID.
User-created nodes must have unique, string IDs. Returns {:error, :duplicate_id}
if a node with the given ID already exists in the tree. Returns {:error, :not_found}
if the parent node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> AtuinStand.Node.create_child(root, "node1")
%AtuinStand.Node{id: "node1", tree: tree}
iex> AtuinStand.Node.create_child(root, "node1")
{:error, :duplicate_id}
Deletes the node from the tree.
Returns {:error, :invalid_operation}
if the node is the root node. Returns
{:error, :not_found}
if the node is not found in the tree.
Provide a strategy
to specify what to do with the node's children:
:refuse
- return{:error, :has_children}
if the node being deleted has children:cascade
- recursively delete the node and all of its children:reattach
- move the node's children to the node's parent before deleting it
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(node1, "node2")
iex> node3 = AtuinStand.Node.create_child(node2, "node3")
iex> AtuinStand.Node.delete(node1, :refuse)
{:error, :has_children}
iex> AtuinStand.Node.delete(node1, :reattach)
iex> AtuinStand.Node.descendants(root)
[node2, node3]
iex> AtuinStand.Node.delete(node2, :cascade)
iex> AtuinStand.Node.descendants(root)
[]
@spec depth(node :: t()) :: non_neg_integer() | {:error, atom()}
Returns the depth of the given node.
For any node, the depth is the number of edges on the path to the root node. The root node has a depth of 0, and every other node has a depth of 1 + its parent's depth.
Equivalent to length(AtuinStand.Node.ancestors(node))
.
Returns {:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> AtuinStand.Node.depth(root)
0
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> AtuinStand.Node.depth(node1)
1
iex> node2 = AtuinStand.Node.create_child(node1, "node2")
iex> AtuinStand.Node.depth(node2)
2
Returns a list of all descendants of the given node.
Provide :dfs
or :bfs
as an optional argument to return the results in
depth-first or breadth-first order, respectively. Defaults to :dfs
.
Returns {:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(node1, "node2")
iex> node3 = AtuinStand.Node.create_child(node2, "node3")
iex> node4 = AtuinStand.Node.create_child(root, "node4")
iex> AtuinStand.Node.descendants(node1, :dfs)
[node2, node3]
iex> AtuinStand.Node.descendants(root, :bfs)
[node1, node4, node2, node3]
Returns the user-defined data associated with the node.
If the node is not found, returns {:error, :not_found}
.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> AtuinStand.Node.create_child(root, "node1")
iex> AtuinStand.Tree.node(tree, "node1")
...> |> AtuinStand.Node.set_data(%{"name" => "Node 1"})
...> |> AtuinStand.Node.get_data()
%{"name" => "Node 1"}
Moves the node after the given node.
Returns {:error, :invalid_operation}
if the node is the root node or if the move would create
a cycle in the tree. Returns {:error, :not_found}
if either node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(root, "node2")
iex> node3 = AtuinStand.Node.create_child(root, "node3")
iex> AtuinStand.Node.move_after(node1, node3)
iex> AtuinStand.Node.children(root)
[node2, node3, node1]
Moves the node before the given node.
Returns {:error, :invalid_operation}
if the node is the root node or if the move would create
a cycle in the tree. Returns {:error, :not_found}
if either node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(root, "node2")
iex> node3 = AtuinStand.Node.create_child(root, "node3")
iex> AtuinStand.Node.move_before(node3, node1)
iex> AtuinStand.Node.children(root)
[node3, node1, node2]
@spec move_to(node :: t(), new_parent :: t(), index :: non_neg_integer() | nil) :: t() | {:error, atom()}
Moves the node to a new parent node.
Returns {:error, :invalid_operation}
if the node is the root node or if the move
would create a cycle in the tree. Returns {:error, :not_found}
if the either node
is not found in the tree.
Provide an optional index
to specify the position of the node in the new parent's
child list. The node will be inserted at the end if no index is provided.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(node1, "node2")
iex> node3 = AtuinStand.Node.create_child(node2, "node3")
iex> AtuinStand.Node.move_to(node1, node3)
{:error, :invalid_operation}
iex> AtuinStand.Node.move_to(node2, root)
iex> AtuinStand.Node.children(root)
[node1, node2]
iex> AtuinStand.Node.move_to(node3, root, 1)
iex> AtuinStand.Node.children(root)
[node1, node3, node2]
iex> AtuinStand.Node.move_to(node2, root, 1)
iex> AtuinStand.Node.children(root)
[node1, node2, node3]
Returns the parent of the given node.
Returns {:error, :not_found}
if the node is not found in the tree.
Returns {:error, :invalid_node}
if the node is the root node.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> AtuinStand.Node.parent(root)
{:error, :invalid_node}
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> AtuinStand.Node.parent(node1)
%AtuinStand.Node{id: :root, tree: tree}
iex> fake_node = %AtuinStand.Node{id: "fake", tree: tree}
iex> AtuinStand.Node.parent(fake_node)
{:error, :not_found}
@spec reposition(node :: t(), index :: non_neg_integer()) :: t() | {:error, atom()}
Moves the node to a new position amongst its siblings.
Returns {:error, :invalid_operation}
if the node is the root node. Returns
{:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(root, "node2")
iex> node3 = AtuinStand.Node.create_child(root, "node3")
iex> AtuinStand.Node.reposition(node2, 0)
iex> AtuinStand.Node.children(root)
[node2, node1, node3]
iex> AtuinStand.Node.reposition(node2, 2)
iex> AtuinStand.Node.children(root)
[node1, node3, node2]
Sets the user-defined data associated with the node. Returns the node.
The data must be a map, otherwise returns {:error, :invalid_data}
. When the
tree is serialized to JSON, the data is serialized as well, so any atom keys
will be converted to strings.
If the node is not found, returns {:error, :not_found}
.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> AtuinStand.Node.create_child(root, "node1")
iex> AtuinStand.Tree.node(tree, "node1")
...> |> AtuinStand.Node.set_data(%{"name" => "Node 1"})
...> |> AtuinStand.Node.get_data()
%{"name" => "Node 1"}
Returns a list of all siblings (other nodes with the same parent) of the given node.
Returns {:error, :not_found}
if the node is not found in the tree.
Examples
iex> tree = AtuinStand.Tree.new()
iex> root = AtuinStand.Tree.root(tree)
iex> node1 = AtuinStand.Node.create_child(root, "node1")
iex> node2 = AtuinStand.Node.create_child(root, "node2")
iex> node3 = AtuinStand.Node.create_child(root, "node3")
iex> AtuinStand.Node.siblings(node1)
[node2, node3]