pub trait DisplayTree {
// Required method
fn fmt(&self, f: &mut Formatter<'_>, style: Style) -> Result;
}
Expand description
A type that can be pretty-printed as a tree with a specified style.
DisplayTree
can be derived for struct
s and enum
s, and generally the
derived implementation should be sufficient, but it can be manually
implemented if needed.
§Deriving
Deriving DisplayTree
for a type requires that all of its fields not
marked #[tree]
implement std::fmt::Display
. A derived implementation
will be formatted as the name of the struct
or variant as a node, followed
by a branches underneath with a node for each field.
The AsTree
type should be used to display a tree implementing
DisplayTree
. See the AsTree
documentation for more
information.
use display_tree::{format_tree, AsTree, DisplayTree};
// A tree representing a numerical expression.
#[derive(DisplayTree)]
enum Expr {
Int(i32),
BinOp {
#[node_label]
op: char,
#[tree]
left: Box<Self>,
#[tree]
right: Box<Self>,
},
UnaryOp {
#[node_label]
op: char,
#[tree]
arg: Box<Self>,
},
}
let expr: Expr = get_expr();
assert_eq!(
format_tree!(expr),
concat!(
"+\n",
"├── -\n",
"│ └── Int\n",
"│ └── 2\n",
"└── Int\n",
" └── 7",
),
);
§Helper Attributes
[derive(DisplayTree)
] provies a few helper attribute that allow the
derived implementation to be customized.
§Field Attributes
-
#[tree]
marks a field that should be formatted as a tree. By default, a field’sstd::fmt::Display
implementation will be used to format it in the tree, but fields can be marked with#[tree]
to use theirDisplayTree
implementation instead.#[tree]
can be used on any type that conforms toToDisplayTreeRef
, which includes any types that conform toDisplayTree
. -
#[ignore_field]
marks a field that should not be included in the tree. When the tree is formatted, the field will not be present. -
#[node_label]
causes a field to be used as the label of the node of the tree that it is under. By default, the name of thestruct
or variant will be used as the label. For example, for a variant representing a binary operator and its arguments, you might want the operator to be the used as the label of the tree. -
#[field_label (= "label")]
causes the node for a field to have a label in the formlabel: value
when it is formatted. A string literal can be passed to specify the label, otherwise the name of the field will be used.
§Struct/Variant Attributes
#[node_label = "label"]
specifies the label to use for the node of the tree. By default, the name of thestruct
or variant will be used.
§Examples
Specifying a field label:
#[derive(display_tree::DisplayTree)]
struct Point {
#[field_label]
x: i32,
#[field_label]
y: i32,
}
Ignoring a field:
#[derive(display_tree::DisplayTree)]
struct Numbers {
not_so_secret_number: i32,
// `super_secret_number` not included when tree is formatted.
#[ignore_field]
super_secret_number: i32,
}
Using a field as the node label:
#[derive(display_tree::DisplayTree)]
enum Expr {
Num(i32),
BinOp {
// Show the operator as the node of this variant.
#[node_label]
op: char,
#[tree]
left: Box<Self>,
#[tree]
right: Box<Self>,
},
}
Using a custom node label:
#[derive(display_tree::DisplayTree)]
// Use "MyStruct" as the node label instead of the name of the `struct`.
#[node_label = "MyStruct"]
struct MyVeryLongComplexDetailedImportantStruct(bool);
Required Methods§
Sourcefn fmt(&self, f: &mut Formatter<'_>, style: Style) -> Result
fn fmt(&self, f: &mut Formatter<'_>, style: Style) -> Result
Formats the tree using the given formatter and the given style.
fmt()
should not be called directly. It is used
by AsTree
to format a tree.
§Examples
use display_tree::{AsTree, DisplayTree, Style};
struct Point {
x: i32,
y: i32,
}
impl DisplayTree for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>, style: Style) -> std::fmt::Result {
writeln!(f, "Point")?;
writeln!(
f,
"{}{} x: {}",
style.char_set.connector,
std::iter::repeat(style.char_set.horizontal)
.take(style.indentation as usize)
.collect::<String>(),
self.x
)?;
write!(
f,
"{}{} y: {}",
style.char_set.end_connector,
std::iter::repeat(style.char_set.horizontal)
.take(style.indentation as usize)
.collect::<String>(),
self.y
)
}
}
assert_eq!(
format!("{}", AsTree::new(&Point { x: 10, y: 20 })),
"Point\n\
├── x: 10\n\
└── y: 20",
);