ruast
This crate provides a printable & modifiable Rust AST.
Features
- Indentation-aware pretty-printing
- Operator precedence-aware pretty-printing
- Fuzzable AST nodes (with
arbitrarycrate)
Basic usage
Hello world
use *;
let mut krate = new;
let def = Fnmain;
krate.add_item;
println!;
// krate.dump("test.rs")?;
// krate.compile("test.rs", CompileOptions::default())?;
krate.try_remove_item_by_id;
assert!;
This is equivalent to:
use *;
let mut krate = new;
krate.add_item;
println!;
// krate.dump("test.rs")?;
// krate.compile("test.rs", CompileOptions::default())?;
krate.try_remove_item_by_id;
assert!;
> cargo run --example hello
Operations
use *;
let lhs = int;
let rhs = int;
let add = lhs.clone.add;
assert_snapshot!;
let add_add = add.clone.add;
assert_snapshot!;
let mul_add = add.mul;
assert_snapshot!;
let mul = lhs.clone.mul;
let add_mul = mul.add;
assert_snapshot!;
let add = lhs.neg.add;
assert_snapshot!;
Building struct, enum, trait and impl
The source code is available in the examples directory.
use *;
let mut krate = new;
let def = empty
.with_field
.with_field;
krate.add_item;
let imp = empty
.with_item;
krate.add_item;
println!;
use *;
let mut krate = new;
let def = empty
.with_variant
.with_variant;
krate.add_item;
let imp = empty
.with_item;
krate.add_item;
println!;
use *;
let mut krate = new;
let partial_eq = simple_path;
let trait_def = new;
krate.add_item;
let arg_t = Type;
let eq_bound = Trait;
let eq = simple_path;
let param_t = new;
let self_ty = poly_path;
let imp = trait_impl;
krate.add_item;
println!;
Convert to proc_macro2::TokenStream
By enabling a feature tokenize, you can convert ruast ASTs to proc_macro2::TokenStream.
You can build ASTs systematically without using syn or quote macros.
use *;
let mut krate = new;
let def = Fnmain;
krate.add_item;
let tokens = krate.to_token_stream;
println!;
println!;
You can also find examples on how to create a proc macro using this crate in examples/proc_macro_example.
Fuzzing
By enabling a feature fuzzing, you can use arbitrary crate to generate random AST nodes for fuzz testing.
Note: The generated AST nodes are entirely random and may not be compilable.
use Arbitrary;
let mut u = new;
set;
let expr = arbitrary.unwrap;
println!;
Feature flags
tokenize: Enables conversion toproc_macro2::TokenStream.checked-ident: Enablescheck_ident,Identifier, etc.fuzzing: Enablesarbitraryimplementations for AST nodes for fuzz testing.
Why this is needed?
The Rust project has a submodule called rustc_ast that defines an AST, but it is not published on crates.io and requires a huge build of rust itself. Also, rustc_ast is not designed for third parties to build ASTs by hand.
There is a codegen crate for Rust code generation, but this crate has not been maintained for some time and only supports basic syntax elements.
There is also a syn crate that can parse proc_macro::TokenStream into an AST, but its AST elements don't implement Display trait and are not designed for direct construction & modification.
Goals
The goal of this project is to provide a simple and portable Rust AST building/Rust code generation library.
Non-goals
This library is not directly related to the Rust compiler AST, and ASTs built with this library cannot be directly given as input to the compiler.
License
This project is licensed under either of Apache license version 2.0 or MIT license at your option.