Docs.rs
  • is-tree-0.9.1
    • is-tree 0.9.1
    • Docs.rs crate page
    • Apache-2.0
    • Links
    • Homepage
    • Repository
    • crates.io
    • Source
    • Owners
    • notdanilo
    • Dependencies
      • enum-as-inner ^0.6.0 normal
      • is-tree-macro ^0.9.1 normal
    • Versions
    • 82.67% of the crate is documented
  • Go to latest version
  • Platform
    • i686-pc-windows-msvc
    • i686-unknown-linux-gnu
    • x86_64-apple-darwin
    • x86_64-pc-windows-msvc
    • x86_64-unknown-linux-gnu
  • Feature flags
  • docs.rs
    • About docs.rs
    • Privacy policy
  • Rust
    • Rust website
    • The Book
    • Standard Library API Reference
    • Rust by Example
    • The Cargo Guide
    • Clippy Documentation

Crate is_tree

is_tree0.9.1

  • All Items
  • Modules
  • Macros
  • Derive Macros

Crates

  • is_tree
?
Settings

Crate is_tree

source ·
Expand description

§is-tree

Convert everything into a tree structure that supports multi-type visitors for tree iterators and relative access.

§Fully-featured example

use is_tree::*;
 
visitor! {
    pub enum Visitors, VisitorsMut {
        Root(Library visits [Module]),
        Branches(
            Module visits [Module, Function],
            Function
        )
    }
}
 
#[derive(Debug, IsTree)]
pub struct Library {
    #[tree(path_segment)]
    #[tree(branch(String))]
    pub name: String,
    #[tree(branch(Module, String))]
    pub root_module: Module
}
 
#[derive(Debug, Default, IsTree)]
pub struct Function {
    #[tree(path_segment)]
    #[tree(branch(String))]
    pub name: String
}
 
#[derive(Debug, Default, IsTree)]
pub struct Module {
    #[tree(path_segment)]
    #[tree(branch(String))]
    pub name: String,
    #[tree(branch(Module, String))]
    pub modules: Vec<Module>,
    #[tree(branch(Function, String))]
    pub functions: Vec<Function>
}
 
// AddBranch<T> is logic-dependent so you need to implement it yourself.
impl AddBranch<Module> for Library {
    fn add_branch(&mut self, module: Module) -> &mut Module {
        self.root_module = module;
        &mut self.root_module
    }
}
 
impl AddBranch<String> for Library {
    fn add_branch(&mut self, name: String) -> &mut String {
        self.name = name;
        &mut self.name
    }
}
 
impl AddBranch<Module> for Module {
    fn add_branch(&mut self, branch: Module) -> &mut Module {
        self.modules.push(branch);
        self.modules.last_mut().unwrap()
    }
}
 
impl AddBranch<Function> for Module {
    fn add_branch(&mut self, branch: Function) -> &mut Function {
        self.functions.push(branch);
        self.functions.last_mut().unwrap()
    }
}
 
impl AddBranch<String> for Module {
    fn add_branch(&mut self, name: String) -> &mut String {
        self.name = name;
        &mut self.name
    }
}
 
impl Library {
    pub fn mock() -> Self {
        Library {
            name: String::from("library"),
            root_module: Module {
                name: String::from("math"),
                modules: vec![
                    Module {
                        name: String::from("geometry"),
                        modules: vec![Module { name: String::from("shapes"), .. Default::default() }],
                        .. Default::default()
                    },
                    Module {
                        name: String::from("algebra"),
                        functions: vec![Function { name: String::from("exponential") }],
                        .. Default::default()
                    },
                ],
                .. Default::default()
            },
        }
    }
}
 
fn main() {
    let mut library = Library::mock();
     
    // Getting the String branches of the structure.
    library.branches_mut::<&mut String>().for_each(|s| *s = s.to_uppercase());
    library.branches::<&String>().for_each(|s| println!("{}", s));
 
    // Getting a Module of the structure.
    library.get_mut::<&mut Module>("MATH").unwrap().name.push_str("EMATICS");
    println!("{}", library.get::<&Module>("MATHEMATICS").unwrap().name);
 
    // Getting an mutable tree visitor.
    let iterator: TreeIterator<VisitorsMut> = TreeIterator::new(&mut library);
    iterator.for_each(|mut visitor| {
        match &mut visitor {
            VisitorsMut::Library(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
            VisitorsMut::Module(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
            VisitorsMut::Function(visitor) => visitor.value.name = visitor.value.name.to_lowercase()
        }
    });
 
    // Getting a constant tree visitor.
    let iterator: TreeIterator<Visitors> = TreeIterator::new(&library);
    iterator.for_each(|visitor| println!("{}", visitor.path_segment()));
 
    // Getting the root visitor.
    let root_visitor = Visitors::from(&library);
 
     // Root don't have a parent.
    assert!(root_visitor.parent().is_none());
 
    // Root is the root of the structure.
    assert_eq!(root_visitor.root().as_library().unwrap().value.name, "library");
 
    // "self", "super" amd "root" are special path segments.
    assert_eq!(root_visitor.relative(vec!["self"]).unwrap().path(), Path::from(vec!["library"]));
 
    // Accessing Module structure.
    assert_eq!(root_visitor.relative(vec!["mathematics"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
 
    // Using "super".
    assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "super"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
 
    // Access a Function structure.
    assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential"]).unwrap().as_function().unwrap().value.name, "exponential"); 
 
    // This is allowed.
    assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential", "root"]).unwrap().as_library().unwrap().value.name, "library"); 
 
    // Mutably accessing the visitor's parent is unsafe because it allows you to get two mutable references to the same object.
    unsafe {
        let mut root_visitor = VisitorsMut::from(&mut library);
 
        assert!(root_visitor.parent_mut().is_none());
 
        root_visitor.root_mut().as_library_mut().unwrap().value.name = "LIBRARY".into();
 
        root_visitor.relative_mut(vec!["mathematics"]).unwrap().as_module_mut().unwrap().value.name = "MATHEMATICS".into(); 
    }
}

Re-exports§

  • pub use traits::*;
  • pub use path::*;
  • pub use visitor::*;
  • pub use tree_iterator::*;

Modules§

  • path
  • prelude
    Re-export of all the modules in the crate.
  • traits
    Traits for working with trees.
  • tree_iterator
    Tree iterator.
  • unsafe_
    Unsafe traits and functions cautiously used in the library but made unsafe to discourage their external use.
  • visitor
    Visitor pattern for tree traversal.
  • visitor_macro

Macros§

  • chain
  • visitor
    ! A macro for generating visitor types. Example:

Derive Macros§

  • IsTree

Results

trait
is_tree::traits::has_root::HasRoot
A trait for types that have a root.
module
is_tree::traits::has_root
A trait for types that have a root.
trait
is_tree::traits::has_root::UnsafeHasRoot
A trait for types that have a root mutably. By design, …
trait method
is_tree::traits::has_root::HasRoot::root
Gets the root of the object.
trait method
is_tree::traits::has_root::HasRoot::root
Gets the root of the object.