8 个版本
0.4.0 | 2021年6月6日 |
---|---|
0.3.1 | 2020年3月20日 |
0.2.5 | 2019年7月1日 |
0.2.4 | 2019年5月21日 |
在 调试 分类中排名 179
每月下载 645 次
用于 2 个 代码包中
73KB
1.5K SLoC
调试树
此库允许您逐个元素构建树,并以漂亮的字符串形式输出。
树可以轻松输出到 String
、stdout
或文件。
这对于从嵌套和递归函数中生成干净的输出尤其方便。
递归 Fibonacci 示例
在 factors()
函数的开始处使用 add_branch!()
宏,您可以以最小的努力生成整个调用树。
use debug_tree::*;
fn factors(x: usize) {
add_branch!("{}", x); // <~ THE MAGIC LINE
for i in 1..x {
if x % i == 0 {
factors(i);
}
}
}
fn main() {
// output to file at the end of this block
defer_write!("examples/out/fibonacci.txt");
add_branch!("A Fibonacci Tree");
factors(6);
add_leaf!("That's All Folks!");
}
A Fibonacci Tree
├╼ 6
│ ├╼ 1
│ ├╼ 2
│ │ └╼ 1
│ └╼ 3
│ └╼ 1
└╼ That's All Folks!
概述
-
添加分支
add_branch!("Hello, {}", "World")
- 分支将在当前块的末尾退出
-
添加叶子节点
add_leaf!("I am a {}", "leaf")
- 已添加到当前作用域的分支
-
在块结束时打印树,或将它写入文件
defer_print!()
defer_write!("filename.txt")
- 这些调用之后树将为空
- 为防止清除,请使用
defer_peek_print!
和defer_peek_write!
-
使用命名树处理多个树
add_branch_to!("A", "I'm a branch on tree 'A'")
add_leaf_to!("A", "I'm a leaf on tree 'A'")
defer_print!("A")
defer_write!("A", "filename.txt")
-
获取命名树
tree("TREE_NAME")
-
从树中检索漂亮的字符串
tree("TREE_NAME").string()
-
跨线程使用
default_tree()
是每个线程本地的- 命名树在线程间共享
更多示例
多个标记树
如果您需要多个独立的树,可以使用名称标签。
use debug_tree::*;
fn populate(tree_name: &str, n_children: usize) {
add_branch_to!(tree_name, "{} TREE", tree_name);
for _ in 0..n_children {
populate(tree_name, n_children / 2);
}
}
fn main() {
// Override tree config (just for "B")
let b_tree = tree("B");
b_tree.set_config_override(
TreeConfig::new()
.indent(4)
.symbols(TreeSymbols::with_rounded().leaf("> ")),
);
defer_write!(b_tree, "examples/out/multiple_trees_B.txt");
defer_write!("A", "examples/out/multiple_trees_A.txt");
populate("A", 2);
populate("B", 3);
}
A TREE
├╼ A TREE
│ └╼ A TREE
└╼ A TREE
└╼ A TREE
B TREE
├──> B TREE
│ ╰──> B TREE
├──> B TREE
│ ╰──> B TREE
╰──> B TREE
╰──> B TREE
嵌套函数
分支也使得嵌套函数调用更容易追踪。
use debug_tree::*;
fn a() {
add_branch!("a");
b();
c();
}
fn b() {
add_branch!("b");
c();
}
fn c() {
add_branch!("c");
add_leaf!("Nothing to see here");
}
fn main() {
defer_write!("examples/out/nested.txt");
a();
}
a
├╼ b
│ └╼ c
│ └╼ Nothing to see here
└╼ c
└╼ Nothing to see here
行断
多行字符串中的换行将被自动缩进。
use debug_tree::*;
fn main() {
// output to file at the end of this block
defer_write!("examples/out/multi_line.txt");
add_branch!("1");
add_leaf!("1.1\nAnother line...\n... and one more line");
add_leaf!("1.2");
}
1
├╼ 1.1
│ Another line...
│ ... and one more line
└╼ 1.2
恐慌
即使发生恐慌,树也不会丢失!defer_
函数被引入,以便在发生 panic!
或早期返回时将树打印或写入文件。
use debug_tree::*;
fn i_will_panic() {
add_branch!("Here are my last words");
add_leaf!("Stay calm, and try not to panic");
panic!("I told you so...")
}
fn main() {
// output to file at the end of this block
defer_write!("examples/out/panic.txt");
// print at the end of this block
{
add_branch!("By using the 'defer_' functions");
add_branch!("Output will still be generated");
add_branch!("Otherwise you might lose your valuable tree!");
}
add_branch!("Now for something crazy...");
i_will_panic();
}
By using the 'defer_' functions
└╼ Output will still be generated
└╼ Otherwise you might lose your valuable tree!
Now for something crazy...
└╼ Here are my last words
└╼ Stay calm, and try not to panic
无宏
如果您不喜欢使用宏,您可以手动构造 TreeBuilder
。
use debug_tree::TreeBuilder;
fn main() {
// Make a new tree.
let tree = TreeBuilder::new();
// Add a scoped branch. The next item added will belong to the branch.
let mut branch = tree.add_branch("1 Branch");
// Add a leaf to the current branch
tree.add_leaf("1.1 Child");
// Leave scope early
branch.release();
tree.add_leaf("2 Sibling");
// output to file
tree.write("examples/out/no_macros.txt").ok(); // Write and flush.
}
1 Branch
└╼ 1.1 Child
2 Sibling
依赖关系
~48KB