We really appreciate and value contributions. Make sure you read those guidelines before starting to make sure your contributions are aligned with project's goals.
You should always include tests and documentation (e.g. comments) where needed.
To guarantee smooth cooperation and limit redundancies, follow these steps to contribute to the repo:
-
ask for assignment on an issue by commenting on it 🙋♂️.
- It is strongly recommended to indicate the ideas you have to solve the issue (technical conception, architectural choices, etc.) to help maintainers understand your implementation.
-
wait for assignment by maintainers.
- you can ping maintainers on discord.
-
open a pull request or draft pull request and ask for review 💁
-
wait for approval and meeeerge! ✅ 🔥
As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests.
The pull requests will be reviewed and eventually merged into the main repo. See "Fork-a-Repo" for methodology.
In order to setup a local environment, please follow the instructions in the README.
-
Making use of clippy:
A collection of lints to catch common mistakes and improve your Rust code.
- Update your Rust version: run
rustup update
- Install clippy: run
rustup component add clippy
- Run clippy and receive some tips: run
cargo clippy
- Update your Rust version: run
-
expect()
andunwrap()
:- You should avoid using these methods as much as possible as they make the current thread panic. As a general rule, we want to handle error cases.
- There are some rare cases where
expect()
andunwrap()
are suitable. Then, comment your code and share your reasoning with your co-contributors: why did you need and properly use these methods?Hint: If you’re having trouble remembering how to phrase expect error messages remember to focus on the word “should” as in “env variable should be set by blah” or “the given binary should be available and executable by the current user”.
- Example - a specific environment variable is essential to your code's execution:
let path = std::env::var("IMPORTANT_PATH").expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
-
Error handling: Rust enables a comprehensive Error handling flow. One can define structs/enums items that implement the trait Error. Then, any third party library or code higher in the execution flow can catch and respond properly to failed states. - In this project, we use thiserror to describe and construct errors. A good example of this is compile.rs.
``` #[derive(Error, Debug)] pub enum Error { #[error("binary '{CAIRO_COMPILE_BINARY}' not found{0}")] CairoCompileBinaryNotFound(#[from] WhichError), #[error("failed to execute a process: {0}")] RunProcess(io::Error), #[error("binary '{0}' failed to compile '{1}'")] Compilation(String, String), #[error("file '{0}' has no stem")] StemlessFile(String), #[error("cache directory does not exist on thiplatform")] CacheDirSupported, #[error("failed to create file '{0}': {1}")] FileCreation(String, io::Error), #[error("failed to create directory '{0}': {1}")] DirCreation(String, io::Error), #[error("failed to write to file '{0}': {1}")] WriteToFile(String, io::Error), } ``` - One cool feature is to be able to raise _transparent_ errors: > Errors may use error(transparent) to forward the source and source methods straight through to an underlying error without adding an additional message. This would be appropriate for enums that need an "anything else" variant. ```rust #[derive(Error, Debug)] pub enum MyError { #[error(transparent)] Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error } ``` This is appropriate for enums that need an "anything else"/other variant. It's also useful when your enum variant can be constructed from multiple types of error. It is the equivalent of `Box<dyn Enum>`
For more, refer to the Idiomatic Rust repository. It regroups all the good practices and elegant flows that Rust enables us to write. For instance, error handling is described in this article, written by Edgar Luque.
To build the project, run the following command:
cargo build
To launch all tests, run:
cargo test