{"id":17644434,"url":"https://github.com/vigna/rust-dev-guidelines","last_synced_at":"2026-02-23T23:32:52.856Z","repository":{"id":227672828,"uuid":"772099690","full_name":"vigna/rust-dev-guidelines","owner":"vigna","description":"Rust Development Guidelines at the Laboratory for Web Algorithmics","archived":false,"fork":false,"pushed_at":"2026-02-19T10:43:15.000Z","size":37,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-19T15:15:10.901Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vigna.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-03-14T14:35:05.000Z","updated_at":"2026-02-19T10:43:19.000Z","dependencies_parsed_at":"2024-05-28T22:54:34.918Z","dependency_job_id":"e6a43e4d-542d-4bf3-a5d4-3b6d7e631740","html_url":"https://github.com/vigna/rust-dev-guidelines","commit_stats":null,"previous_names":["vigna/rust-dev-guidelines"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vigna/rust-dev-guidelines","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigna%2Frust-dev-guidelines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigna%2Frust-dev-guidelines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigna%2Frust-dev-guidelines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigna%2Frust-dev-guidelines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vigna","download_url":"https://codeload.github.com/vigna/rust-dev-guidelines/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigna%2Frust-dev-guidelines/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29760617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T21:02:23.375Z","status":"ssl_error","status_checked_at":"2026-02-23T20:58:31.539Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":[],"created_at":"2024-10-23T10:05:26.313Z","updated_at":"2026-02-23T23:32:52.850Z","avatar_url":"https://github.com/vigna.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rust Development Guidelines at the Laboratory for Web Algorithmics\n\nThis file details the guidelines for developing Rust code at the Laboratory for\nWeb Algorithmics. It is a document _in fieri_, and will be updated as\nnecessary.\n\nThese guidelines extend the [Rust API\nGuidelines](https://rust-lang.github.io/api-guidelines/about.html).\n\nFor CLI commands, follow the [Command-Line Interface Guidelines](https://clig.dev/).\n\n## Tools\n\n- Code should be `cargo clippy --all-features --all-targets`-clean.\n\n- Use `rustfmt` with standard options to format the code. Formatting should\n  be enabled as a save action in the editor to reduce the number of spurious\n  difference in commits due to spacing and formatting.\n\n- To release new versions:\n  - run `cargo c --all-targets --all-features`;\n  - run `cargo +nightly fuzz build` if necessary;\n  - run `cargo doc --all-features --document-private-items` and check the generated docs;\n  - run `cargo deadlinks`;\n  - run `cargo t --all-features --all-targets`, which will include the `slow_tests` feature,\n    if available;\n  - bump the version number;\n  - run [`cargo semver-checks`](https://crates.io/crates/cargo-semver-checks);\n  - update the change log;\n  - commit the changes;\n  - publish the crate (in case of a crate with procedural macros,\n    first publish the procedural macros, then test again the main\n    crate, and finally publish the main crate);\n  - create an annotated tag for the new release with `git tag -m\"Release VERSION\" VERSION`;\n  - add on GitHub a new titleless release associated with the newly created tag,\n    and a message given by the entry of the change log.\n\n## Naming Conventions\n\n- \u003chttps://github.com/rust-lang/rfcs/blob/master/text/0344-conventions-galore.md\u003e\n\n- As in the Rust standard libraries, traits should use the indefinite/imperative\n  form of a verb, whereas implementing structures should use a qualified agent\n  associated with the verb: for example, the trait `Read` is implemented by\n  `BufReader`. See “Trait Naming” in the link above.\n\n- Modules are directories containing a `mod.rs` file. They should have plural\n  names for countables, as in `traits`, `impls`, `utils`, `tests`, and singular\n  names for uncountables, such as `fuzz`. Module names should be (very) short.\n\n- Modules that contain a single trait or structure should not be public, and\n  the trait or structure should be re-exported by the module that contains it.\n  Otherwise, the module should be public and should contain documentation about\n  its content.\n\n## Structure of Source Files\n\nIn source files, information about types should appear in this order:\n\n- declaration;\n- implementations of derivable traits;\n- macros (constructors, etc.);\n- inherent implementations;\n- implementations of traits from the crate;\n- implementations of external crates;\n- implementations of traits from the standard library.\n\n## Structures\n\n- In structures, the first declared fields should be the immutable ones (e.g.,\nthose that do not change value in the lifetime of the structure) followed by the\nmutable ones. In each section, fields should be ordered from the most\ngeneral/important to the least general/important. In particular, chains of\ndependence should be reflected by the field order.\n\n- `impl` blocks should minimize the trait bounds of the type parameters. This is\n  a concern similar to\n  [C-STRUCT-BOUNDS](https://rust-lang.github.io/api-guidelines/future-proofing.html#c-struct-bounds).\n  For example,\n\n  ```rust\n  impl\u003cS: Read + Seek\u003e Foo\u003cS\u003e {\n      pub fn bar(seek: S) -\u003e std::io::Result\u003cu64\u003e {\n          seek.stream_position()\n      }\n  }\n  ```\n\n  should be\n\n  ```rust\n  impl\u003cS: Seek\u003e Foo\u003cS\u003e {\n      pub fn bar(seek: S) -\u003e std::io::Result\u003cu64\u003e {\n          seek.stream_position()\n      }\n  }\n\n## Traits\n\n- Always implement `ExactSizeIterator`/`ExactSizeLender` and\n  `FusedIterator`/`FusedLender` when possible\n\n## Methods\n\n- Rust does not allow for optional parameters with default values, but often one\nsimulates them implicitly using `Option` or special values. In functions and\nmethods, the first parameters should be the compulsory ones, followed\nby the optional ones. In each section, arguments should be ordered from the most\ngeneral/important to the least general/important. In particular, chains of\ndependence should be reflected by the argument order.\n\n- Prefer `impl Trait` over type parameters whenever possible.\n  For example,\n\n  ```rust\n  pub fn doit\u003cP: AsRef\u003cPath\u003e\u003e(a: P) {\n\n  }\n  ```\n\n  is better written as\n\n  ```rust\n  pub fn doit(a: impl AsRef\u003cPath\u003e) {\n\n  }\n  ```\n\n  Possible reasons for using type parameters instead of `impl Trait` include:\n  - the type parameter is used in the return type of the function or method;\n  - the type parameter is used in the body of the function or method.\n\n- Type parameters and `impl Trait` parameters should minimize trait bounds. This\n  is a concern similar to\n  [C-STRUCT-BOUNDS](https://rust-lang.github.io/api-guidelines/future-proofing.html#c-struct-bounds).\n  For example,\n\n  ```rust\n  pub fn bar(seek: impl (Read + Seek)) -\u003e std::io::Result\u003cu64\u003e {\n      seek.stream_position()\n  }\n  ```\n\n  should be\n\n  ```rust\n  pub fn bar(seek: impl Seek) -\u003e std::io::Result\u003cu64\u003e {\n      seek.stream_position()\n  }\n\n- There are a few standard preferences in argument types:\n  - always prefer receiving an `IntoIterator` rather than an `Iterator`;\n  - always prefer receiving a `AsRef\u003cstr\u003e` rather than a `String`, `\u0026str`, or\n      `\u0026String`;\n  - always prefer receiving a `AsRef\u003cPath\u003e` rather than a `Path`, `\u0026Path`, or\n      `\u0026PathBuf`;\n  - always prefer receiving a reference to a slice rather than a more specific\n    data structure like a vector.\n\n## Tests\n\n- Test functions should be named `test_` followed by a brief description of the\n  feature tested, e.g., `test_long_input`. If a source file contains tests for\n  more than one structure, the test functions might sport a disambiguating\n  suffix after `test_`—for example, the name of the structure.\n\n- Test functions must return `anyhow::Result\u003c()\u003e` and use the `?` operator,\n  avoiding `unwrap` and `expect` unless absolutely necessary.\n\n- Assertions in tests must sport first the actual value, and then the expected\n  value. For example,\n\n  ```rust\n  assert_eq!(bit_read.read_gamma(), 2);\n  ```\n\n- Unit tests that need to access the private parts of a structure should be\n  added directly at the end of the source file as\n\n  ```rust\n  #[cfg(test)]\n  mod tests {\n      use super::*;\n\n      #[test]\n      fn test_long_input() -\u003e anyhow::Result\u003c()\u003e {\n      }\n  }\n  ```\n\n- Unit-test functions should be named `test_` followed by a brief description of\n  the tested structure, or the specific feature tested.\n\n- Longer, end-to-end, and possibly slow tests should be placed in a separate\n  file named `test_*` in the `tests` directory.\n\n- Very slow tests should be gated with the feature `slow_tests`. Ideally, `cargo\n  test` should not take more than a few seconds to run.\n\n## Macros\n\n- In macros, one should always specify structures and traits starting from `::`\n  to avoid relative resolution. This does not fix the problem of crates\n  shadowing modules in the standard library, but if that happens there are much\n  bigger problems to attend to. The most readable approach is adding a `use\n  ::...` statement at the beginning each method body. Then, you can just use the\n  name of the structure or trait.\n\n- Note that in declarative macros you can use `$crate::` to refer to items in\n  the current crate.\n\n- Trait methods in macros and generated code should use the [fully qualified\n  syntax](https://doc.rust-lang.org/book/ch20-02-advanced-traits.html) rather\n  than the dot syntax, to avoid unpredictable method-resolution issues. Inherent\n  methods can use the dot syntax.\n\n## Logging\n\n- All binaries and tests using logging (e.g., a `ProgressLogger`) must configure\n  an `env_logger` with\n\n  ```rust\n      env_logger::builder()\n          .filter_level(log::LevelFilter::Info)\n          .try_init()?;\n  ```\n\n  or\n\n  ```rust\n      env_logger::builder()\n          .is_test(true)\n          .filter_level(log::LevelFilter::Info)\n          .try_init()?;\n  ```\n\n  for tests.\n\n## Errors\n\n- \u003chttps://github.com/rust-lang/rfcs/blob/master/text/0236-error-conventions.md\u003e\n\n## Documentation\n\n- \u003chttps://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md\u003e\n\n- An additional documentation section `Implementation Notes` can be used to\n  gather details of the implementation that are not relevant to the user.\n\n- Functions and methods should be documented [in this\n  way](https://doc.rust-lang.org/rust-by-example/meta/doc.html).\n\n- Function arguments need not be documented explicitly if the meaning is\n  evident from the naming; otherwise, they should be documented as follows:\n\n  ```rust\n  /// # Arguments\n  ///\n  /// * `a` - The first argument, and note that lines should be max 80 characters\n  /// long to facilitate reading.\n  ///\n  /// * `b` - The second argument. Note the empty line above.\n  ///\n  /// * `c` - The third argument. Note the empty line below.\n  ```\n\n- As discussed in the reference above, links should be written in reference\n  style, and the references should be placed at the end of the documentation\n  block.\n\n- The main crate documentation must be placed in a `README.md` file that\n  is included by `lib.rs` using `#![doc = include_str!(\"../README.md\")]`.\n  All links in the `README.md` file should be written in reference style, using\n  absolute URLs, possibly pointing to the latest version of the crate on\n  `docs.rs` for the crate, as in\n\n  ```md\n  [`MemCase`]: \u003chttps://docs.rs/epserde/latest/epserde/deser/mem_case/struct.MemCase.html\u003e\n  ```\n\n- Each project should sport a change log named `CHANGELOG.md` with the\n  following sample format:\n\n  ```md\n  # Change Log\n\n  ## [0.0.1] - 1970-01-02\n\n  ### New\n\n  * New feature, and note that lines should be max 80 characters long to\n    facilitate reading.\n\n  * Other new feature.\n\n  ### Changed\n\n  * Something changed (not new, not an improvement, not a fix).\n\n  ### Improved\n\n  * Improvement.\n\n  ### Fixed\n\n  * Bug fix.\n\n\n  ## [0.0.0] - 1970-01-01\n\n  ### New\n\n  * New feature.\n\n  ### Changed\n\n  * Something changed (not new, not an improvement, not a fix).\n\n  ### Improved\n\n  * Improvement.\n\n  ### Fixed\n\n  * Bug fix.\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvigna%2Frust-dev-guidelines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvigna%2Frust-dev-guidelines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvigna%2Frust-dev-guidelines/lists"}