Rust project template
My workflow to create a project in Rust and configure a few basic things to get started.
The template already contains the following things:
- vscode workspace configuration
- structured logging
- a script with useful commands which can read environment variables
Prerequisites
Install rust
- via rustup
- via nix flake (install nix and open nix flake development shell)
Create project
You can create a rust project manually or use my rust template on GitHub
Use GitHub template
- go to my template repo on GitHub (link above) and click the green button Use this template
- GitHub will create a new repo with the content of the template
- adjust your project package name
- in
Cargo.toml
- in
src/utils/logging.rs
(adjust the project variable)
- in
- then you are already ready to run your app
Create project manually
- alternatively these are the steps to create a new project manually
- this section only describes a simpler version (only structured logging, cli via
clap
only part of template repo)
Init cargo project
- in existing git repo
cargo init .
Visual Studio Code configuration
- configure your vscode workspace
Recommended extensions
.vscode/extensions.json
{
"recommendations": [
"rust-lang.rust-analyzer",
"yzhang.markdown-all-in-one",
"tamasfe.even-better-toml",
"usernamehw.errorlens",
"vadimcn.vscode-lldb",
"fill-labs.dependi"
]
}
Useful vscode settings
.vscode/settings.json
{
"files.trimFinalNewlines": true,
"files.insertFinalNewline": true,
"[rust]": {
"editor.detectIndentation": false,
"editor.insertSpaces": true,
"editor.tabSize": 4
},
"[toml]": {
"editor.detectIndentation": false,
"editor.insertSpaces": true,
"editor.tabSize": 4
},
"editor.tabSize": 2,
"editor.detectIndentation": false,
"editor.insertSpaces": false,
// "rust-analyzer.linkedProjects": [
// "projects/project-01/Cargo.toml",
// "projects/project-02/Cargo.toml",
// "projects/project-03/Cargo.toml"
// ],
"rust-analyzer.inlayHints.typeHints.enable": false,
"rust-analyzer.inlayHints.parameterHints.enable": false
}
Configure structured logging
Add dependencies for structured logging
- add the following to your dependenciesCargo.toml
[dependencies] log={ version = "0.4.26", features = ["kv", "kv_serde"] } env_logger={ version = "0.11.6", features = ["unstable-kv"] }
- run
cargo check
- run
cargo run
- everything should still work
- run
Use structured logger
Example project main.rs
- this example configure a structured logger in
main.rs
- you can control log levels per module via the environment variable
RUST_LOG
- check the provided links in additional resources section for more details
ℹ️
In case you want to copy this example you should set the
project
variable to your package name.src/main.rs
use log;
use std::env;
fn main() {
let mut custom_env_var_rust_log = true;
if env::var("RUST_LOG").is_err() {
custom_env_var_rust_log = false;
// https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html
// simple default: set all to warn
// let env_var_value = format!("warn");
// let env_var_value = "warn";
// project naming: use underscore instead of dash! (example package name: rust-project-template)
let project = "rust_project_template";
// set level per module and default to warn
// let env_var_value = "warn,module_ab=info,{project}::module_xy::sub_module_12=debug";
// project main ist just {project}
let env_var_value = format!("warn,{project}=info");
// ensure that the environment access only happens in single-threaded code.
unsafe { env::set_var("RUST_LOG", env_var_value) };
}
let rust_log = env::var("RUST_LOG").unwrap();
// env_logger::init();
env_logger::builder()
.format_file(true)
.format_line_number(true)
.init();
if !custom_env_var_rust_log {
log::info!(rust_log; "initialized logger with project default module level configuration");
} else {
log::info!(rust_log; "initialized logger with custom module level configuration (set via environment variable 'RUST_LOG'")
}
println!("Hello, world!");
}
Example other module
- just import the log module and use it
src/example_module/example_submodule.rs
use log;
// your code
Run your app
Basic run command
- you can run the code via
cargo run
Extra command for template repo example
- use cli arguments after two dashes
--
when running the program viacargo
# cli help cargo run -- -h # example run cargo run -- --name Julius --count 3
Adjust log levels per module
- set the environment variable
RUST_LOG
to configure log levels per module
ℹ️
Do not forget to adapt the module naming according to your package name which is not
rust_project_template
I suppose.Set env var inline
RUST_LOG="warn,rust_project_template::example_module::example_submodule=debug" cargo run
Use .env file with bash script
- create a file called
.env
in the root dir of the repoRUST_LOG="warn,rust_project_template::example_module::example_submodule=debug"
- run you app with the following command
./ctl.sh cargo:run
Configure debugging
- install vscode extension CodeLLDB (
vadimcn.vscode-lldb
) - open
main.rs
file - open debug tab
- click run debug
- vscode will detect
Cargo.toml
and provide a default debug configuration - now you can add breakpoints and click the debugging button to add a debug session
Additional resources
Logging
- enable log level per module via env variable
- structured logging via log kv feature
- configure kv for env_logger
- set env is unsafe since rust 2024
- use format macro
- use
log_enabled
to avoid expensive computation of log message arguments if the message would be ignored anyway
rust-analyzer
- vscode multiple projects
- use linked projects instead of multiple workspaces?!
Debugging with CodeLLDB
- vscode extension
- vscode docs info about security stuff
- use this command to avoid password prompt forever
sudo DevToolsSecurity --enable
- use this command to avoid password prompt forever
Updated on