Status: Alpha. There's some risk of corrupting source code (mostly when dealing with rare syntax elements, comments in odd places). Some corruption will be caught and you'll be alerted with no changes to the file. But commit your code before running if possible.
Named after Gene Michaels.
Dog fooded in this repo.
Run cargo install genemichaels
If you're using vs code, add the setting:
"rust-analyzer.rustfmt.overrideCommand": [
"${userHome}/.cargo/bin/genemichaels"
]
to use it with reckless abandon.
Do cargo add genemichaels
There's one main function at the moment:
genemichaels::format_str
- takes a string (full rust source file, doesn't support snippets at the moment) and formatting config, returns a struct containing the formatted string and any comments that weren't included in the output.genemichaels::format_ast
- takes any formattable AST element (implements genemichaels::Formattable
), the config, and any comments associated with the source from which the AST element was originally derived (this will probably be empty for generated code). It returns the same as the above.This formats macros.
It assumes your macros look and act mostly like normal rust constructs (especially regarding whitespace and trailing commas). If this isn't the case, you should fix the macros or use rustfmt
instead.
At a very high level:
For instance, a split group for match {}
might have segments match
{
newline-if-split
and }
. These segments are interleaved (other group's segments may come between {
and }
) in a single line, to start.
If the split group is triggered to split, newline-if-split
and everything after it on that line are moved to a new line after the line they were on.
Comments deserve a special mention since they're handled out of band.
syn` doesn't parse comments (except sometimes) so all the comments are extracted at the start of processing.
When building split groups, if the current syntax element has a token with a line/column matching an extracted comment, the comment is added to the split group.
Any unused comments cause an error to be raised.
At the moment, the formatted code is run through the parser again. This doesn't catch everything (like some omitted elements), but prevents some totally broken output.