#递归 #AST #过程宏 #格式化输出 #

ast2str

一个用于格式化输出AST和其他递归数据结构的crate

6个稳定版本

1.4.1 2022年8月19日
1.4.0 2022年8月2日
1.3.0 2022年7月31日
1.2.1 2021年9月6日
1.1.1 2021年9月4日

#705数据结构

37 每月下载量

MIT 协议

49KB
675

ast2str

crates.io Documentation Build Status

一个用于格式化输出AST和其他递归数据结构的过程宏。

基本用法

请参考以下代码片段以获取基本用法示例,并查看集成测试以及这两个仓库(#1.1 + #1.2#2.1)以获取更大的示例。

// 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());

可用属性

属性
None 使用 AstToStr 格式化值
#[forward] 跳过所有其他字段,并返回注释字段的 AstToStr
#[skip] 跳过注释字段
#[display] 使用 Display 代替 AstToStr 格式化注释字段
#[debug] 使用 Debug 代替 AstToStr 格式化注释字段
#[quoted] 类似于 #[display] 但也会用反引号包裹值
#[list] 通过执行 AstToStr 在 (&field).into_iter() 的每个元素上格式化注释字段
#[list(name_or_closure) 通过在 (&field).into_iter() 的每个元素上应用回调来格式化注释字段
#[callback(name_or_closure)] 将给定的函数或闭包应用于 &field 并返回结果
#[delegate = "getter"] 调用 self.getter() 并将结果格式化为字段
#[默认值 = ""] 仅适用于 Option 类型。如果值为 Some(T),则使用 AstToStr 格式化 &T。否则,返回 default 的值
#[skip_if = "my_condition_fn"] 如果指定的函数返回 true,则跳过注解的字段

依赖项

~1.2–1.7MB
~39K SLoC