Skip to content

Releases: jngls/syntaxfmt

Hotfix v0.2.2

01 Nov 18:35
096f68a

Choose a tag to compare

This release fixes a subtle issue in the following context:

macro_rules! impl_in_macro {
    ($name:ident) => {
        #[derive(SyntaxFmt)]
        struct $name(i32);
    };
}
impl_in_macro!(InMacro);

Which would give error error[E0424]: expected value, found module self on the derive(SyntaxFmt).

The issue was that I was incorrectly using quote_spanned. It only showed its face when wrapped in macros where the hygeine context is different than regular usage.

What's Changed

  • Fixed hygeine context error
  • Minor doc updates
  • Bump version number

Hotfix v0.2.1

30 Oct 13:47
36afe86

Choose a tag to compare

This fixes the infinite trait resolution compile issue caused by things like:

#[derive(SyntaxFmtDerive)]
#[syntax(bound = DummyBound)]
struct MutualRecursiveA<'a> {
    b: MutualRecursiveB<'a>,
    _marker: PhantomData<&'a i32>,
}

#[derive(SyntaxFmtDerive)]
#[syntax(bound = DummyBound)]
struct MutualRecursiveB<'a> {
    a: Vec<MutualRecursiveA<'a>>,
    _marker: PhantomData<&'a i32>,
}

I was incorrectly overspecifying bounds. This has been commented out and will be removed fully in a future version if it's definitely not needed.

Summary

  • Removed overspecified where bounds added by proc macro
  • Add comprehensive example
  • Bumped version to 0.2.1
  • Minor doc tweaks

v0.2.0

30 Oct 02:25
59044a8

Choose a tag to compare

This is a complete re-write of the proc macro code and addition of specific impls to address the Display blanket impl code gen explosion.

It contains breaking changes so be sure to check the migration notes.

Summary

  • Complete proc macro rewrite
  • Reduced blanket implementation sprawl
  • Better Rust compatibility
    • Relaxed edition to 2021
    • Relaxed MSRV to 1.70
  • Docs update
  • Readme update
  • Version bump to 0.2.0
  • Split prefix and suffix args
    • pre for specifying prefix, eg pre = "prefix_"
    • suf for specifying suffix, eg suf = "_suffix"
    • The old format string was not a real format string in the vein of format!(...), nor did it reduce character counts in syntax attribute arguments, so it was removed
  • Content replacement
    • cont allows for field or type content replacement and accepts any value that implements SyntaxFmt
    • cont_with allows for field or type content replacement using functions or closures
  • Automatic layout control
    • ind for specifying indent regions. Actually writing the indentation is now automatic as long as you use the new nl argument.
    • nl for writing newlines to various locations beg (beginning), pre (after prefix), cont (after field or type content), suf (after suffix).
    • Multiple inserted newlines are possible via array syntax, eg nl = [beg, suf]
    • newline builder method of SyntaxDisplay for setting newline character sequences, eg syntax_fmt(&...).newline(["", "\r\n"])
    • indent builder method of SyntaxDisplay now takes array parameter, eg syntax_fmt(&...).indent(["", "\t"])
  • Most args can now take optional array syntax for modal customisation (to distinguish between normal and pretty)
    • delim can now optionally take array syntax, eg delim = ["::", " :: "]
    • pre can optionally take array syntax, eg pre = ["normal_prefix_", "pretty_prefix_"]
    • suf can optionally take array syntax, eg suf = ["_normal_suffix", "_pretty_suffix"]
    • cont can optionally take array syntax, eg cont = ["normal", "***pretty***"]
  • Better conditional field evaluation
    • eval allows for conditional field evaluation logic using direct field access
    • eval_with allows for conditional field evaluation logic using functions or closures
    • #[syntax_else(...)] attribute allows for full formatting of eval and eval_with "else" case
  • Better control over state types
    • bound specifies the trait bound to be passed through for custom formatters and explicit SyntaxFmt implementations
    • state specifies the concrete state type to be passed through for custom formatters and explicit SyntaxFmt implementations

Breaking Changes and Migration Notes

  • Attribute argument changes
    • In cases where you used format, use pre = "prefix_" and/or suf = "_suffix" or to define different prefixes and suffixes depending on mode (normal or pretty), use pre = ["normal_prefix_", "pretty_prefix_"] and/or suf = ["_normal_suffix", "_pretty_suffix"] (see Adding Decorations)
    • In cases where you used pretty_format, use pre and/or suf as explained above for format
    • In cases where you used pretty_delim, use delim = ["normal", "pretty"] instead (see Collections and Delimiters)
    • In cases where you used empty_suffix, use eval = xyz followed by the new attribute #[syntax_else(...)] on a new line (see Conditional Formatting and Fallback Format)
    • In cases where you used indent, remove it (indentation is now automatic as long as you use the new nl arg) (see Indentation and Layout)
    • In cases where you used indent_region, use ind (see Indentation and Layout)
    • In cases where you used state_bound, use bound (see Additional State Examples)
  • Newlines and indentation
    • Previously, it was required to place newlines inline in format or delim strings. You can still inline newlines in pre, suf, and delim strings, but you should try to instead use the new nl attribute arg as it deals with automatic indentation (see Indentation and Layout)
    • Previously, it was required to manually specify the indent attribute on every field or type. Now, all newlines triggered by the nl attribute arg are automatically indented (see Indentation and Layout)

Alpha v0.1.0

19 Oct 22:34

Choose a tag to compare

Alpha v0.1.0 Pre-release
Pre-release

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

syntaxfmt provides a trait-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 optional formatting.

Features

  • Derive macro - Automatic implementation of formatting logic with #[derive(SyntaxFmt)]
  • Dual formatting modes - Compact and pretty-printed output with .pretty() method chaining
  • Optional state - No boilerplate for stateless formatting, easy state passing when needed
  • Collection support - Automatic formatting for Vec<T>, &[T], and [T; N] types
  • Boolean and Option support - Conditional formatting for bool and Option<T> types
  • Stateful formatting - Pass user-defined context through the formatting process
  • Custom formatters - Override default behavior with custom functions or by explicitly implementing SyntaxFmt
  • Flexible attributes - Control delimiters, indentation, and format strings per-field and per-type
  • Customizable indentation - Use spaces, tabs, or any custom string

More Info

syntaxfmt
syntaxfmt docs