syntaxfmt 0.2.2

A derive macro-based library for flexible syntax tree formatting with pretty printing support.
Documentation

syntaxfmt

Crates.io MIT License APACHE 2.0 License

A derive macro-based library for flexible syntax tree formatting with pretty printing support.

syntaxfmt provides a trait and builder based approach to formatting syntax trees with both compact and pretty-printed output modes. It's designed for compiler frontends, code generators, and any application that needs to format structured data as text with dynamic formatting.

Features

  • Derive Macro - Automatic implementation via #[derive(SyntaxFmt)]
  • Flexible Decorations - Add prefixes, suffixes, and collection delimiters
  • Modal Formatting - Customise formatting output for different modes, normal and pretty
  • Automatic Layout - Automated layout control with newlines and indentation
  • Content Replacement - Override field formatting with literals or custom functions
  • Conditional Formatting - Format based on arbitrary boolean expressions, with else support
  • Stateful Formatting - Pass mutable or immutable state for context-aware output

Cargo Features

  • derive (enabled by default) - Enables the SyntaxFmt derive macro

Getting Started

Add syntaxfmt to your Cargo.toml:

[dependencies]
syntaxfmt = "0.2.2"

Quick Start

The simplest use case is to derive SyntaxFmt on your types and they'll format themselves by printing each field in order:

use syntaxfmt::{SyntaxFmt, syntax_fmt};

#[derive(SyntaxFmt)]
struct BinaryOp<'src> {
    left: &'src str,
    op: &'src str,
    right: &'src str,
}

let expr = BinaryOp { left: "x", op: "+", right: "y" };
assert_eq!(format!("{}", syntax_fmt(&expr)), "x+y");

Adding Decorations

Use pre (prefix) and suf (suffix) attributes to add syntax around fields:

use syntaxfmt::{SyntaxFmt, syntax_fmt};

#[derive(SyntaxFmt)]
#[syntax(pre = "let ", suf = ";")]
struct LetStatement<'src> {
    name: &'src str,

    #[syntax(pre = " = ")]
    value: &'src str,
}

let stmt = LetStatement { name: "x", value: "42" };
assert_eq!(format!("{}", syntax_fmt(&stmt)), "let x = 42;");

Basic Pretty Printing

Enable pretty printing with the .pretty() method. Use modal attributes (arrays) to specify different formatting for normal vs pretty mode:

use syntaxfmt::{SyntaxFmt, syntax_fmt};

#[derive(SyntaxFmt)]
struct FunctionCall<'src> {
    name: &'src str,

    #[syntax(pre = ["(", "( "], suf = [")", " )"], delim = [", ", ",  "])]
    args: Vec<&'src str>,
}

let call = FunctionCall {
    name: "max",
    args: vec!["x", "y", "z"],
};

assert_eq!(format!("{}", syntax_fmt(&call)), "max(x, y, z)");
assert_eq!(format!("{}", syntax_fmt(&call).pretty()), "max( x,  y,  z )");

More advanced pretty printing is available via Indentation and Layout.

Further Reading and More Examples

For complete documentation including many more examples, visit docs.rs/syntaxfmt.

Attribute Summary

Attributes can be applied at the type, field, or syntax_else level.

Argument Description Valid Location
pre Text before content field/type/else
suf Text after content field/type/else
delim Separator between collection elements field/type/else
cont Literal replacement for field value field/type/else
cont_with Custom formatter function/closure field/type/else
eval Conditional expression field/type
eval_with Conditional function/closure field/type
nl Newline positions (beg, pre, cont, suf) field/type/else
ind Increase indent level for field content field/type/else
skip Omit field from formatting field/type
state Specify state type (type-level only) type
bound Add trait bound to state (type-level only) type

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is dual licensed under:

Unless explicitly stated otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.