A collection of Rust abstract syntax tree transformations, which target unidiomatic (and possibly unsafe!) code constructs that appear in Rust code generated by C-to-Rust code generators, e.g. https://c2rust.com/.
This library provides an API to analyze and transform Rust source code, or even its underlying AST, as represented by a syn::File
object.
(See https://crates.io/crates/syn for more information about the crate::syn
parsing library.)
The monadicast
library exposes a public MonadicAst
struct, which can be constructed from
a string of Rust source code with its constructor or from the syn::File
AST itself.
With a given MonadicAst
, one can
- obtain its held AST, consuming the struct:
MonadicAst::ast()
, - obtain a string representing the formatted source code corresponding to the AST:
MonadicAst::result()
, - apply a transformation to the held AST, e.g.
MonadicAst::convert_ffi_types()
.
use monadicast::MonadicAst;
use std::error::Error;
use std::fs;
fn main() -> Result<(), Box<dyn Error>> {
let content = fs::read_to_string("./example/input.rs")?;
let output = MonadicAst::new(&content)?
// apply some transformations to the AST...
.convert_ffi_types()
.replace_raw_pointers()
.translate_while_to_for_loops()
// ...and finally convert the AST back to a source code string
.result();
fs::write("./example/output.rs", output)?;
Ok(())
}
Note: If you couldn't tell from the name, this library imposes a monadic structure around the syn::File
abstract syntax tree datatype. If you are familiar with monads, the conventional unit is the From<syn::File>
method and each AST transformation is a bind (>>=) on the MonadicAst
struct.
If you aren't familiar with monads, check out
this stack overflow post
and/or this blog post about them.
There is also more complete documentation in the source code, which can be found by reading the RustDoc in src/monad/ast.rs
.