Crate orange_trees

Crate orange_trees 

Source
Expand description

§orange-trees

orange-trees is a Rust implementation of the Tree data structure

§Get Started

§Add orange-trees to your dependencies

orange-trees = "0.1"

§Initialize a tree

Orange-trees provides three ways to initialize trees:

  1. using the node! macro
  2. Using the with_child constructor nested structure
  3. Using with_children
use orange_trees::{Tree, Node};

// Create a tree using macro
let tree: Tree<&'static str, &'static str> = Tree::new(
  node!("/", "/"
    , node!("/bin", "bin/"
      , node!("/bin/ls", "ls")
      , node!("/bin/pwd", "pwd")
    )
    , node!("/tmp", "tmp/"
      , node!("/tmp/dump.txt", "dump.txt")
      , node!("/tmp/omar.txt", "omar.txt")
    )
  )
);

// Create a tree using constructor
let tree: Tree<&'static str, &'static str> = Tree::new(
  Node::new("/", "/")
    .with_child(
      Node::new("/bin", "bin/")
        .with_child(Node::new("/bin/ls", "ls"))
        .with_child(Node::new("/bin/pwd", "pwd"))
      )
    .with_child(
      Node::new("/tmp", "tmp/")
        .with_child(Node::new("/tmp/dump.txt", "dump.txt"))
        .with_child(Node::new("/tmp/omar.txt", "omar.txt"))
        .with_child(
          Node::new("/tmp/.cache", "cache/")
            .with_child(Node::new("/tmp/.cache/xyz.cache", "xyz.cache"))
        )
    ),
);

// With-children

let tree: Tree<String, &str> =
    Tree::new(Node::new("a".to_string(), "a").with_children(vec![
        Node::new("a1".to_string(), "a1"),
        Node::new("a2".to_string(), "a2"),
    ]));

§Query a tree

There are many functions to query nodes’ attributes, such as their value, their depth and their children. In addition to these, there are also functions to search nodes by predicate or by id.

use orange_trees::{Node, Tree};

let tree: Tree<&'static str, &'static str> = Tree::new(
  Node::new("/", "/")
    .with_child(
      Node::new("/bin", "bin/")
        .with_child(Node::new("/bin/ls", "ls"))
        .with_child(Node::new("/bin/pwd", "pwd"))
      )
    .with_child(
      Node::new("/tmp", "tmp/")
        .with_child(Node::new("/tmp/dump.txt", "dump.txt"))
        .with_child(Node::new("/tmp/omar.txt", "omar.txt"))
        .with_child(
          Node::new("/tmp/.cache", "cache/")
            .with_child(Node::new("/tmp/.cache/xyz.cache", "xyz.cache"))
        )
    ),
);
// Query tree
let bin: &Node<&'static str, &'static str> = tree.root().query(&"/bin").unwrap();
assert_eq!(bin.id(), &"/bin");
assert_eq!(bin.value(), &"bin/");
assert_eq!(bin.children().len(), 2);
// Find all txt files
let txt_files: Vec<&Node<&'static str, &'static str>> = tree.root().find(&|x| x.value().ends_with(".txt") && x.is_leaf());
assert_eq!(txt_files.len(), 2);
// Count items
assert_eq!(tree.root().query(&"/bin").unwrap().count(), 3);
// Depth (max depth of the tree)
assert_eq!(tree.root().depth(), 4);

§Manipulate trees

Orange-trees provides a rich set of methods to manipulate nodes, which basically consists in:

  • Adding and removing children
  • Sorting node children
  • Truncating a node by depth
use orange_trees::{Node, Tree};

let mut tree: Tree<&'static str, &'static str> = Tree::new(
  Node::new("/", "/")
    .with_child(
      Node::new("/bin", "bin/")
        .with_child(Node::new("/bin/ls", "ls"))
        .with_child(Node::new("/bin/pwd", "pwd"))
      )
    .with_child(
      Node::new("/tmp", "tmp/")
        .with_child(Node::new("/tmp/dump.txt", "dump.txt"))
        .with_child(Node::new("/tmp/omar.txt", "omar.txt"))
        .with_child(
          Node::new("/tmp/.cache", "cache/")
            .with_child(Node::new("/tmp/.cache/xyz.cache", "xyz.cache"))
        )
    ),
);

// Remove child
tree.root_mut().query_mut(&"/tmp").unwrap().remove_child(&"/tmp/.cache");
assert!(tree.root().query(&"/tmp/.cache").is_none());
// Add child
tree.root_mut().add_child(Node::new("/var", "var/"));
// Clear node
tree.root_mut().query_mut(&"/tmp").unwrap().clear();
assert_eq!(tree.root().query(&"/tmp").unwrap().count(), 1);
// Sort tree
let mut tree: Tree<&'static str, usize> = Tree::new(
    Node::new("/", 0)
        .with_child(Node::new("8", 8))
        .with_child(Node::new("7", 7))
        .with_child(Node::new("3", 3))
        .with_child(Node::new("1", 1))
        .with_child(Node::new("2", 2))
        .with_child(Node::new("9", 9))
        .with_child(Node::new("5", 5))
        .with_child(Node::new("4", 4))
        .with_child(Node::new("6", 6)),
);
tree.root_mut()
    .sort(|a, b| a.value().partial_cmp(b.value()).unwrap());
let values: Vec<usize> = tree.root().iter().map(|x| *x.value()).collect();
assert_eq!(values, vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);

§Working with routes

Whenever you want to track the state of the tree (such as tracking opened nodes or selected one), routes come handy to do so. Routes are basically the path, described by child index, to go from the parent node to the child node. You can get the route for a node and then the node associated to a route with two simple functions:

use orange_trees::{Node, Tree};

let tree: Tree<String, &str> = Tree::new(
    Node::new("/".to_string(), "/")
    .with_child(
        Node::new("/bin".to_string(), "bin/")
            .with_child(Node::new("/bin/ls".to_string(), "ls"))
            .with_child(Node::new("/bin/pwd".to_string(), "pwd")),
    )
    .with_child(
        Node::new("/home".to_string(), "home/").with_child(
            Node::new("/home/omar".to_string(), "omar/")
                .with_child(Node::new("/home/omar/readme.md".to_string(), "readme.md"))
                .with_child(Node::new(
                    "/home/omar/changelog.md".to_string(),
                    "changelog.md",
                )),
        ),
    ),
);
// -- node_by_route
assert_eq!(
    tree.root().node_by_route(&[1, 0, 1]).unwrap().id(),
    "/home/omar/changelog.md"
);
// -- Route by node
assert_eq!(
    tree.root()
        .route_by_node(&"/home/omar/changelog.md".to_string())
        .unwrap(),
    vec![1, 0, 1]
);

Macros§

node
Create a new Node using a macro

Structs§

Node
Describes a node inside the Tree U: is the type for the node indentifier (must implement PartialEq) T: is the type for the node value
Tree
represent the tree data structure inside the component. U: is the type for the Node indentifier (must implement PartialEq) T: is the type for the Node value