Custom-tailored Configuration for Code Quality Tools in Rust

Reading Time: 4 minutes

Code quality is one of the most important aspects of programming world. As it impacts our overall software quality i.e., how safe, secure, and reliable our codebase is.

This image has an empty alt attribute; its file name is untitled-diagram-4.png

Code quality is not only to perform efficiently but also to make code more readable. 

Essentially, code that is considered good:

A code should be:

  • readable,
  • follows consistent style,
  • testable,
  • well documented,
  • follows Single Responsibility Approach

To achieve this we have some tools in Rust Programming:

  • Clippy: A tool to improve code quality of the Rust Project.
  • Rustfmt: A tool for formatting Rust code according to style guidelines.

Clippy

It is a code completion tool for helping developers of a library or application to write better code. Clippy uses lints to improve code quality.

Lint is a program that supports checking the source code for Programmatic and Stylistic errors, which makes it more helpful for identifying some common or uncommon mistakes during code development process.

Lint majorly focuses on:

  • preventing discrepancy 
  • coherence to coding standards
  • provides logical errors in your program

Some lint groups are already enabled by default:

  • clippy::style
  • clippy::correctness
  • clippy::complexity
  • clippy::perf

clippy::style

Used for code that should be written in a more idiomatic way.

clippy::correctness

Helps to detect hard error code. 

clippy::complexity

Prevents to write complex code.

clippy::perf

Provides ability to write code in a faster way.

Lints that can be configured in Rust Stable

  • blacklisted-name 
  • too-many-arguments 
  • enum-variant-names
  • single-char-binding-names-threshold
  • cognitive-complexity-threshold
  • max-fn-params-bools
  • max-struct-bools
  • too-many-lines-threshold

blacklisted_name:

Contains a list of names that are blacklisted to use in a program. 

Input Type: Vec<String>
Default value: ["foo", "bar", "baz", "quux"]
Category:  Style

Example: blacklisted-names = [“blacklist_name1”, “blacklist_name2”]

too_many_arguments:

Sets the threshold of number of arguments for a function.

Input Type: u64
Default value: 7
Category:  Complexity

Example: too-many-arguments-threshold = 7

enum_variant_names:

Denotes the minimum number of variants for an enum.

Input Type: u64
Default value: 3
Category:  Style

Example: enum-variant-name-threshold = 3

many_single_char_names:

Sets the minimum number of single characters used in a program.

Input Type: u64
Default value: 4
Category:  Style

Example: single-char-binding-names-threshold = 2

cognitive_complexity:

Check for methods containing high cognitive complexity.

Input Type: u64
Default value: 25
Category:  Nursery

Example: cognitive-complexity-threshold = 20

fn_params_excessive_bools:

Represents maximum number of bools function parameters can have.

Input Type: u64
Default value: 3
Category:  Pedantic

Example: max-fn-params-bools = 2

struct_excessive_bools:

Denotes maximum number of bools a struct can have.

Input Type: u64
Default value: 3
Category:  Pedantic

Example: max-struct-bools = 2

too_many_lines:

Validates maximum number of lines a function can have.

Input Type: u64
Default value: 3
Category:  Pedantic

Example: too-many-lines-threshold = 2

Attributes to allow/deny/warn Clippy lints in your codebase:

Allow#[allow(clippy::lint_group)] 
or, 
Deny#[deny(clippy::lint_group)] 
or else,
Warn#[warn(clippy::lint_group)]

All the properties must be stored in the clippy.toml file.

Example: 

blacklisted-names = ["foo", "too"]
too-many-arguments-threshold = 3
enum-variant-name-threshold = 3
single-char-binding-names-threshold = 0
cognitive-complexity-threshold = 20
max-fn-params-bools = 3
max-struct-bools = 3
too-many-lines-threshold = 30

Note: Instead of using attributes in codebase it’s recommended to pass arguments as a command line with `cargo clippy`

Examples: 

cargo clippy — -W clippy::pedantic   //  warns about pedantic
or,
cargo clippy — -A clippy::pedantic    // allows pedantic
or,
cargo clippy — -D clippy::pedantic    // denies pedantic

Rustfmt

Rustfmt is a tool specifically designed for code indentation and code formatting. It is used to make code more readable and makes code more comprehensive.

Code formatting is a mechanical task that takes both time and effort. By using customized formatting tool, a programmer is relieved of this task and can concentrate on more important things.

Custom configuration of Rustfmt for Rust Stable:

  • max_width 
  • tab_spaces
  • merge_derives
  • reorder_imports
  • fn_args_layout
  • hard_tabs
  • reorder_modules
  • use_field_init_shorthand

max_width:

Represents maximum width of each line.

Default value: 100
Input type: unsigned integer

Example: max_width = 80    // sets 80 chars as a maximum width

tab_spaces:

Denotes number of tabs.

Default value: 4
Input type: unsigned integer

Example: tab_spaces = 4    // sets 4 tab spaces as a maximum

reorder_imports:

Responsible for reordering imports in a lexicographical order.

Default value: true
Input type: boolean

Example: reorder_imports = false    // denies for reorder imports 

merge_derives:

Merge multiple derives into a single one. 

Default value: true
Input type: boolean

Example: merge_derives = false    // disables for merge derive

fn_args_layout:

Represents the layout of parameters in a function signature.

Default value: “Tall”
Input type: "Compressed", “Tall”, “Vertical”

Example: merge_derives = “Compressed”    // allows layout of parameters in compressed form

hard_tabs:

Responsible for allowing/denying of tab spaces.

Default value: false
Input type: boolean

Example: hard_tabs = true    // allows to set tab spaces

reorder_modules:

Helps to reorder modules in a lexicographical manner.

Default value: true
Input type: boolean

Example: reorder_modules = false    //  disables the ordering of modules

use_field_init_shorthand:

Allow us to use field initialization in a compact way.

Default value: false
Input type: boolean

Example: use_field_init_shorthand = true    //  allows field initialization

All the properties must be stored in the rustfmt.toml file.

Example:

max_width = 80
tab_spaces = 4
merge_derives = true
reorder_imports = false
fn_args_layout = "Compressed"
hard_tabs = false
reorder_modules = true
use_field_init_shorthand = true

Thank you for reading!!!

If you want to read more content like this?  Subscribe Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe Rust Times Newsletter: https://bit.ly/2Vdlld7 .

This image has an empty alt attribute; its file name is screenshot-from-2020-06-08-11-00-35.png

Knoldus-blog-footer-image

Written by 

Pawan Singh Bisht is a Software Consultant at Knoldus Software LLP, having a strong experience of more than a year in the technology field. He has been well versed in the core implementation of Rust and Java. He loves to contribute towards the community which he attained from the community.

Leave a Reply