Expand description
A proc macro for pretty-printing ASTs and other recursive data structures.
Basic Usage
Refer to the snippet below for a basic usage example, and see the integration test and these two repos (#1.1 + #1.2, #2.1) for larger samples.
// Import the macro
use ast2str::AstToStr;
type Span = std::ops::Range<usize>;
// Annotate some structs and enums as desired
#[derive(AstToStr)]
struct Label {
#[quoted]
name: &'static str,
#[default = "Unresolved"]
location: Option<usize>,
}
#[derive(AstToStr)]
enum Expr {
Binary {
left: Box<Expr>,
#[quoted]
operator: &'static str,
right: Box<Expr>
},
Literal(#[rename = "value"] i32, #[skip] Span),
List { items: Vec<Expr> },
Label(#[forward] Label),
Optional {
#[skip_if = "Option::is_none"]
value: Option<&'static str>
}
}
let expr = Expr::Binary {
left: Box::new(Expr::Literal(5, Span::default())),
operator: "+",
right: Box::new(Expr::List { items: vec![
Expr::Label(Label { name: "x", location: Some(0) }),
Expr::Label(Label { name: "y", location: Some(1) }),
Expr::Label(Label { name: "z", location: None }),
Expr::Optional { value: None },
Expr::Optional { value: Some("a string") },
]})
};
assert_eq!(expr.ast_to_str(), r#"
Expr::Binary
├─left: Expr::Literal
│ ╰─value: 5
├─operator: `+`
╰─right: Expr::List
╰─items=↓
├─Label
│ ├─name: `x`
│ ╰─location: 0
├─Label
│ ├─name: `y`
│ ╰─location: 1
├─Label
│ ├─name: `z`
│ ╰─location: Unresolved
├─Expr::Optional
╰─Expr::Optional
╰─value: "a string"
"#.trim());
// The symbols used to draw the tree can be configured using the [`Symbols`] trait:
assert_eq!(expr.ast_to_str_impl(&ast2str::TestSymbols), r#"
Expr::Binary
left: Expr::Literal
value: 5
operator: `+`
right: Expr::List
items=
Label
name: `x`
location: 0
Label
name: `y`
location: 1
Label
name: `z`
location: Unresolved
Expr::Optional
Expr::Optional
value: "a string"
"#.trim());
Available Attributes
Attribute | |
---|---|
None | Format the value with AstToStr |
#[forward] | Skip all other fields and return the AstToStr of the annotated field |
#[skip] | Skip the annotated field |
#[display] | Format the annotated field with Display instead of AstToStr |
#[debug] | Format the annotated field with Debug instead of AstToStr |
#[quoted] | Like #[display] but also wraps the value with backticks |
#[list] | Format the annotated field by executing AstToStr on every element of (&field).into_iter() |
#[list(name_or_closure) | Format the annotated field by applying the callback on every element of (&field).into_iter() |
#[callback(name_or_closure)] | Apply the given function or closure to &field and return the result |
#[delegate = "getter"] | Call self.getter() and format the result as a field |
#[default = "value"] | Only applies to Option types. If the value is Some(T) , format &T with AstToStr. Otherwise, return the value of default |
#[skip_if = "my_condition_fn"] | Skip the annotated field if the specified function returns true |
Re-exports
pub use ast2str_derive;
pub use ast2str_lib;
Modules
This module defines the data structures and functions used to draw trees.
Structs
The default set of symbols that produces neatly-drawn trees.
A set of symbols where every symbol is either whitespace (
) or an empty string.
A builder struct for formatting AST nodes.
Traits
A trait for printing ASTs in a pretty manner.
A trait for supplying symbols to the AST formatting functions.