{"id":44484660,"url":"https://github.com/verus-lang/verusfmt","last_synced_at":"2026-02-13T01:48:42.262Z","repository":{"id":206408606,"uuid":"665324893","full_name":"verus-lang/verusfmt","owner":"verus-lang","description":"An Opinionated Formatter for Verus","archived":false,"fork":false,"pushed_at":"2026-02-02T18:55:09.000Z","size":2902,"stargazers_count":15,"open_issues_count":16,"forks_count":11,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-02-03T08:43:51.516Z","etag":null,"topics":["formatter","pretty-printer","verus"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/verus-lang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-12T00:55:46.000Z","updated_at":"2026-02-02T18:55:13.000Z","dependencies_parsed_at":"2023-11-22T22:28:45.914Z","dependency_job_id":"90c71d38-6791-4105-84c4-301e9cf44faf","html_url":"https://github.com/verus-lang/verusfmt","commit_stats":null,"previous_names":["jaybosamiya/verusfmt","verus-lang/verusfmt"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/verus-lang/verusfmt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verus-lang%2Fverusfmt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verus-lang%2Fverusfmt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verus-lang%2Fverusfmt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verus-lang%2Fverusfmt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/verus-lang","download_url":"https://codeload.github.com/verus-lang/verusfmt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verus-lang%2Fverusfmt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29392210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T00:53:09.511Z","status":"ssl_error","status_checked_at":"2026-02-13T00:53:09.126Z","response_time":55,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["formatter","pretty-printer","verus"],"created_at":"2026-02-13T01:48:41.669Z","updated_at":"2026-02-13T01:48:42.250Z","avatar_url":"https://github.com/verus-lang.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Verusfmt\n\nAn opinionated formatter for [Verus] code.\n\n## Updating verusfmt\n\nIf you've installed a pre-built binary, you can update to the latest release using\n```sh\nverusfmt --update\n```\n\n## Installing and Using Verusfmt\n\nWe support multiple install methods. Get the [latest release](https://github.com/verus-lang/verusfmt/releases/latest) using:\n\n- Pre-built binaries (recommended)\n\n  + \u003cdetails\u003e\u003csummary\u003eLinux/MacOS (click to expand)\u003c/summary\u003e\n\n    ```sh\n    curl --proto '=https' --tlsv1.2 -LsSf https://github.com/verus-lang/verusfmt/releases/latest/download/verusfmt-installer.sh | sh\n    ```\n    \u003c/details\u003e\n\n  + \u003cdetails\u003e\u003csummary\u003eWindows (click to expand)\u003c/summary\u003e\n\n    ```sh\n    powershell.exe -ExecutionPolicy RemoteSigned -c \"irm https://github.com/verus-lang/verusfmt/releases/latest/download/verusfmt-installer.ps1 | iex\"\n    ```\n    \u003c/details\u003e\n\n- \u003cdetails\u003e\u003csummary\u003ecargo install (click to expand)\u003c/summary\u003e\n\n  ``` sh\n  cargo install verusfmt --locked\n  ```\n  \u003c/details\u003e\n\nThese will install the `verusfmt` binary. You can then run it on a file using:\n\n``` sh\nverusfmt foo.rs\n```\n\nSee `verusfmt --help` for more options and details.\n\n**Overriding verusfmt**\n\nTo prevent `verusfmt` from processing a particular item or expression, add the `#[verusfmt::skip]` attribute.\n\n## Goals\n\n1. Make it easier to read and contribute to [Verus] code by automatically\n   formatting it in a consistent style (added bonus: eliminating soul-crushing\n   arguments about style).\n2. Produce acceptably \"pretty\" output.\n3. Run fast!  `verusfmt` may be run in pre-submit scripts, CI, etc., so it can't\n   be slow.\n4. Keep the code reasonably simple. Pretty printers are [notoriously\n   hard](https://journal.stuffwithstuff.com/2015/09/08/the-hardest-program-ive-ever-written/),\n   so we try to take steps to reduce that difficulty, so that `verusfmt` can be\n   updated and adapted with a reasonable amount of effort. \n\n### FAQ\n\n1. Why not adapt [`rustfmt`] for [Verus] idioms?\n\n    While Verus has Rust-like syntax, it necessarily also deviates from it to\n    support its idioms naturally, and thus not only would the parser for\n    `rustfmt` need updates, but also careful changes to the emitter would be\n    needed to have code look natural. Additionally, since practically all Verus\n    code is inside the `verus!{}` macro (and `rustfmt` does not easily support\n    formatting even regular Rust inside macros), a non-trivial amount of effort\n    would be required to perform the plumbing and maintenance required to\n    support both formatting _outside_ the `verus!{}` macro (as Rust code), while\n    also formatting Verus code _inside_ the macro.\n\n1. Does `verusfmt` match [`rustfmt`] on code outside the `verus!{}` macro?\n\n    Yes, by default, `verusfmt` handles code inside the `verus!{}` macro, and\n    also runs `rustfmt` to handle code outside the macro. Neither should clash\n    with the other or override each other's formatting changes. Thus, this\n    makes it easier to incrementally verify small amounts of code inside a\n    larger unverified Rust crate.  You can disable the invocation of `rustfmt`\n    using `--verus-only`.\n\n1. Why not build this as a feature of [Verus]?\n\n    By the time Verus receives an AST from `rustc`, we've already lost\n    information about whitespace and comments, meaning that we couldn't preserve\n    the comments in the reformatted code. Plus, firing up all of `rustc` just to\n    format some code seems heavyweight.\n\n## Future Work\n- Special handling for commonly used macros, like `println!`, `state_machine!`\n- Enforce the [Rust naming policy](https://doc.rust-lang.org/beta/style-guide/advice.html#names)? \n\n## Non-Future Work\n- We currently have no plans to sort `use` declarations the way [`rustfmt`] does\n- We do not intend to parse code that [Verus] itself cannot parse.  Sometimes `verusfmt` \n  happens to parse such code, but that is unintentional and cannot be counted upon.\n- Perfectly match the formatting produced by [`rustfmt`]\n- Handle comments perfectly -- they're surprisingly hard!\n\n## Design Overview\n\nOur design is heavily influenced by the [Goals](#Goals) above.  Rather than\nwrite everything from scratch ([a notoriously hard\nundertaking](https://journal.stuffwithstuff.com/2015/09/08/the-hardest-program-ive-ever-written/)),\nwe use a parser-generator to read in Verus source code, and a pretty-printing\nlibrary to format it on the way out.  We try to keep each phase as performant\nas possible, and we largely try to keep the formatter stateless, for\nperformance reasons but more importantly to try to keep the code reasonably\nsimple and easy to reason about.  Hence we sometimes deviate from Rust's style\nguidelines for the sake of simplicity.\n\n### Parsing\n\nWe define the syntax of Verus source code using [this\ngrammar](src/verus.pest), which is processed by the [Pest](https://pest.rs/)\nparser generator, which relies on Parsing Expression Grammars\n([PEG](https://en.wikipedia.org/wiki/Parsing_expression_grammar)s).  It\nconveniently allows us to define our notion of whitespace and comments, which\nthe remaining rules can then ignore; Pest will handle them implicitly.  We\nexplicitly ignore the code outside the `verus!` macro, leaving it to\n[`rustfmt`].  We prefer using explicit rules for string constants, since it\nallows a more uniform style when formatting the code.  In some places, we have\nmultiple definitions for the same Verus construct, so that we can format it\ndifferently depending on the context (see, e.g., `attr_core`).  Many of the\nrules are designed to follow the corresponding description in [The Rust\nReference](https://doc.rust-lang.org/beta/reference/introduction.html).\n\n### Formatting\n\nRather than try to format things ourselves, we rely on the\n[pretty] crate, based on [Philip\nWadler's](https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)\ndesign for a pretty printer.  The core idea is that you create a set of possible\ncode layouts, and the pretty printer then uses its internal heuristics to pick\nthe prettiest version.  Typically this means that we specify where, say, line breaks\ncan occur if the code needs to be placed on multiple lines, but you can also\nuse the `group` operator to say that for a particular code snippet, the pretty printer\nshould also consider placing everying in the group on a single line.\n\nAs much as possible, we try to keep the formatter simple by arranging for the \nformatting of a node to be computed by simply formatting each of its children.\nSometimes this requires splitting a node in the parser, so that we can format\nthe same item in two different ways, depending on its context.  Rust contexts\ncan be tricky to track dynamically (since Rust allows expressions in statements,\nand statements in expression), so we try to keep the formatter stateless to reduce\nthe scope for errors.\n\n## Contributing\n\nWe welcome contributions! Please read on for details.\n\nWe consider it a bug in `verusfmt` if you provide `verusfmt` with code\nthat [Verus] accepts, and `verusfmt` either does not accept/parse it, or\nproduces code that Verus does not accept (or has different semantics from the original).\nWhen this happens, please open a GitHub issue with a minimal example of the offending code\nbefore (and after) formatting.\n\nIf `verusfmt` produces valid code but you dislike the formatting, please open\na GitHub pull request with your proposed changes and rationale for those changes.\nPlease ensure that existing test cases still pass (see below for more details),\nunless your goal is to change how some of those test cases are handled.  Please\nalso include new/updated tests that exercise your proposed changes.\n\n### Tips for Developing a Fix or an Improvement\n\n1. Write out a small example `.rs` file focusing on the specific thing you want\n   to improve.  Test `verusfmt` on your reduced example to make sure the issue\n   still manifests; running with `--check` is very helpful with this process.\n   The smaller your example file, the easier subsequent steps will be.\n2. When running with `--check`, you can also add `-dd` to see 2nd level debug\n   output, which includes the parse tree.  Look through the parse tree and\n   identify rules relevant to your particular example.\n3. Once you find the relevant rule names, if the issue seems to be a misparse,\n   jump over to `src/verus.pest` to find the relevant rule(s) and see if the\n   grammar needs to be fixed or improved.\n4. If the parsing is fine but the printing is an issue, then look for the\n   relevant rule(s) in the `to_doc` function in `src/lib.rs`. This might be a\n   bit difficult to understand immediately, so having the [pretty] docs handy\n   is quite helpful.  Also, it is helpful to look at the relevant debug print\n   (using `-d` or `-dd`), which gives a serialized version of the recursively\n   expanded `doc`, right before it has been optimized, so figuring out which\n   particular bit of it is not behaving as you like is quite helpful.\n5. Attempt fixes until the small example succeeds.\n6. Add the example into the tests---see the [Testing](#testing) section below.\n7. If fixing the rule for your small example succeeds but breaks other tests,\n   you may need to split the relevant rule in the parsing grammar into two\n   separate cases, so that each case can be formatted independently.  See\n   `comma_delimited_exprs_for_verus_clauses`  and\n   `groupable_comma_delimited_exprs_for_verus_clauses`, for example.\n\n## Testing\n\n### Rust-like formatting\n\nIn general, we try to adhere to Rust's style guide.  Tests for such adherence live in\n[tests/rustfmt-matching.rs](tests/rustfmt-matching.rs).  These tests will compare the output\nof [`rustfmt`] to that of `verusfmt`.  You can run them via `cargo test`.\n\n### Verus-like formatting\n\nIn various places, we deviate from Rust's style, either to simplify the\nformatter or to handle [Verus]-specific syntax.  Tests for formatting such code\nlive in [tests/verus-consistency.rs](tests/verus-consistency.rs).  You can add\na new test or modify an existing one by writing/changing the input code.  The\ntest's correct answer is maintained via the [Insta testing framework](https://insta.rs).\n\nInsta recommends installing the `cargo-insta` tool for an improved review experience:\n```\ncargo install cargo-insta\n```\n\nYou can run the tests normally with `cargo test`, but it's often more convenient\nto run the tests and review the results via:\n```\ncargo insta test\ncargo insta review\n```\nor more succinctly:\n```\ncargo insta test --review\n```\n\n\n[Verus]: https://github.com/verus-lang/verus\n[`rustfmt`]: https://github.com/rust-lang/rustfmt\n[pretty]: https://crates.io/crates/pretty\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverus-lang%2Fverusfmt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fverus-lang%2Fverusfmt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverus-lang%2Fverusfmt/lists"}