Skip to content

Latest commit

 

History

History
113 lines (69 loc) · 4.78 KB

Rust Style.md

File metadata and controls

113 lines (69 loc) · 4.78 KB

Contributing Rust code to MaidSafe

We don't maintain a separate style guide but in general try to follow common good practice, write readable and idiomatic code and aim for full test coverage. In addition, this document lists a few decisions we've reached in discussions about specific topics.

Rust version

We currently always use the latest Rust stable toolchain. Please install it using rustup:

https://www.rust-lang.org/tools/install

To update stable:

rustup update stable

Rustfmt

Apply Rustfmt to new code before committing, using the default configuration or, if present, the repository's rustfmt.toml file. We run Rustfmt on the stable toolchain.

To install Rustfmt:

rustup component add rustfmt

To run Rustfmt:

cargo fmt

Clippy

Crates are tested using cargo-clippy; make sure your code does not produce any new errors when running Clippy. If you don't agree with a Clippy lint, discuss it with the team before explicitly adding a #[allow(clippy::<lint>)] attribute. We run Clippy on the stable toolchain.

To install Clippy:

rustup component add clippy

To run Clippy:

cargo clippy
cargo clippy --all-targets

If the crate being tested also defines features, these two Clippy commands should also be run with each feature enabled.

Unwrap

Don't unwrap Options or Results, except possibly when:

  1. locking a mutex,
  2. spawning a thread,
  3. joining a thread,
  4. writing tests or examples

or in other patterns where using them makes the code much simpler and it is obvious at first glance to the reader (even one unfamiliar with the code) that the value cannot be None/Err.

In these cases, prefer to use the macro from the unwrap crate.

Threads

Generally avoid detached threads. Give child threads meaningful names.

This can easily be achieved by preferring to create child threads using maidsafe_utilities::thread::named().

  • it returns a Joiner which helps to avoid detached threads
  • it requires that the child thread is given a name

Function ordering

In impls, always put public functions before private ones.

Bringing names into scope (use statements)

Generally use statements should be employed to bring names from different modules into scope. However, functions from other modules should not be brought fully into scope. Instead their module should be brought into scope meaning that subsequent usage of the function requires one level of qualification. For example, if we have:

pub mod a {
    pub mod b {
        pub struct Harbour {}
        pub fn bar() {}
    }
}

then the normal use statement to bring these into scope would be:

use a::b::{self, Harbour};

Requiring functions to be module-qualified allows generically-named functions to be disambiguated, particularly given that stuttering is discouraged. For example, encode() could exist as a function in modules hex, base32 and base64. That function shouldn't be named e.g. hex::hex_encode(), so when we use it, it's clearer to write hex::encode() rather than just encode().

This policy on imports applies to all repositories apart from safe_client_libs, where functions are also fully brought into scope. This is because the safe_client_libs workspace has many instances of functions which if partially qualified would make the code unnecessarily verbose.

We also have an exception for all repositories using the serialisation functions from maidsafe_utilities. These should always be fully brought into scope, since qualifying any of these with serialisation:: only increases verbosity without any gain in clarity.

Cargo

Use cargo-edit to update dependencies or keep the Cargo.toml in the formatting that cargo-edit uses.

Other crates

Adding new dependencies to MaidSafe crates in general should be discussed in the team first, except if other MaidSafe crates already have the same dependency. E.g. quick-error and unwrap are fine to use.

Git Commit Messages

The first line of the commit message should have the format <type>/<scope>: <subject>. For details see the Leaf project's guidelines.