Cargo Runner
Streamline your Rust development with Cargo Runner, a powerful tool that simplifies your workflow and enhances your productivity.
No Unicorn and crab was harm during the creation of this tool.
Requirements
NOTE: if this are missing then the extension will not be loaded
Features
[x] Command Runner - press CMD+R to run any command on your current cursor position.
[x] Override Rust Analyzer Config - press CMD+SHIFT+R to override any rust-analyzer command.
[x] Cargo Toml Integration - parse useful Metadata
from Cargo.toml
[x] Codelldb Debugger Integration - add breakpoints to debug your code.
[x] Rust Analyzer Integration - Override rust-analyzer
config from vscode settings
[x] Cargo Nextest Integration - Enable / Disable cargo-nextest
from vscode settings
[x] Override $CARGO_HOME from vscode settings (used by cargo-nextest
)
Use cases
Run
read more about cargo run
- Run Main
- Go to your
main.rs
file and press CMD+R
- Other Binaries
- Go to any
src/bin/*.rs
file or to any files declared as [[bin]]
in Cargo.toml
and press CMD+R
- Examples
- Go to any
examples/*.rs
file and press CMD+R
NOTE: main() fn would be the fallback scope on any file , if main() fn exists on that file, considering it as the parent module to run cargo commands on.
Even if your are on main.rs and you don't have main() fn , it would'nt run any cargo commands on that file.
This gives us the ability to run cargo build on any build.rs file even if rust-analyzer
doesn't support it.
Test
read more about cargo test
- Create a test
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
fn it_works_too() {
assert_eq!(2 + 2, 4);
}
}
NOTE: The scope varies , if your cursor is on the scope outside any fn test , it would then go up its parent module and run all the tests in that module. In the example above it would run all test on mod tests as its parent module.
To Enable cargo-nextest
set cargoRunner.enableNextest
to true
in your settings.json
- Press CMD+R on any code block you want to run tests on
Doc test
WARNING: Doc test only works with a crate-type of lib
- Add doc-test on a function e.g.
lib.rs
///
/// ```rust
/// use common::add;
/// assert_eq!(add(1, 2), 3);
/// ```
pub fn add(left: usize, right: usize) -> usize {
left + right
}
doc-test works on any function or method, Struct , Enum and Union that has doc-block and code block of rust
NOTE: The scope varies , if you put your cursor on the Struct definition and that Struct has many doc-test on its impl block then it will run all of them. Same goes for Enum and Union .
- Press CMD+R to run
doc-tests
Debugging
- Add breakpoint on a rust file e.g.
main.rs
or any other rust file
fn main() {
println!("Hello, world!"); <!-- add break point here
}
- Press CMD+R to debug the program
Note: This would only work if codelldb
is installed.
REMINDER: You cannot debug any benchmarks or doc-tests , when you try to debug benches it would just run the cargo bench
Bench
- set version of rust to
nightly
rustup override set nightly
- Add to the root of the module e.g.
main.rs
Root module means
#![feature(test)]
extern crate test;
- create a new bench fn
#[cfg(test)]
mod tests {
use std::time::Duration;
use test::Bencher;
use tokio::{runtime::Runtime, time::sleep};
#[bench]
fn bench_async_example(b: &mut Bencher) {
let runtime = Runtime::new().unwrap();
b.iter(|| {
runtime.block_on(async {
sleep(Duration::from_millis(5000)).await;
let x: u32 = (1..100).sum();
x
});
});
}
}
FEATURE Supports cargo-nextest
to run benchmarks
Overriding/Configuring Rust Analyzer Settings
Rules:
Rule 1: You can either add or remove configurations but at the same time.
Rule 2: You can combine one or more keywords when adding or removing configurations.
Rule 3: Order don't matter when typing keywords to add or remove config. except when you marked the start of test binary args with --
, everything you type there be save as test binary args.
Rule 4: Removing configurations is marked with !
for more info head to Removing Configuration
Usage:
Press CMD+SHIFT+R or bind it to a key you like.
type the params , env, features, target, test binary args you want to add or remove.
Adding configuration
- Adding Cargo Arguments
type: e.g. --release --profile=default
It would be saved on your settings.json
as follows
settings.json
"rust-analyzer.runnables.extraArgs": [
"--release",
"profile=default"
],
example command output:
cargo run --package codec --bin codec --release --profile=default
- Adding Test Binary Args
IMPORTANT: The --
should be added to mark the start of adding test binary args.
type: e.g. -- --quiet --show-output --color=always --nocapture
It would be saved on your settings.json
as follows
settings.json
"rust-analyzer.runnables.extraTestBinaryArgs": [
"--quiet",
"--show-output",
"--color=always",
"--nocapture",
],
This would be used for both cargo test
and cargo-nextest
when generating the command to run.
example command output:
cargo test --package codec --bin codec -- tests::it_works --exact --quiet --show-output --color=always --nocapture
NOTE: To check the allowed args for cargo test
run cargo test -- --help in your terminal.
NOTE To check the allowed args for cargo-nextest
run cargo nextest run --help in your terminal.
- Adding ENV vars
type e.g. RUST_BACKTRACE=full RUST_LOG=debug
it would be saved on your settings.json
as follows
settings.json
"rust-analyzer.runnables.extraEnv": {
"RUST_BACKTRACE": "full",
"RUST_LOG": "debug"
}
- Adding Features
list all features on crates
Resolver version 2 command-line flags
type e.g. --features=example,default --no-default-features
it would be saved on your settings.json
as follows
settings.json
"rust-analyzer.cargo.noDefaultFeatures": true,
"rust-analyzer.cargo.features": [
"example",
"default"
],
example command output:
cargo run --package codec --bin codec --features example --features default --no-default-features
NOTE : This is not recommended for workspaces setup as any features define here would also be applied to all crates in the workspace.
For better control over features , check Bonus section.
- Add Target
type e.g. --target=wasm32-unknown-unknown
It would be saved on your settings.json
as follows
settings.json
{
"rust-analyzer.cargo.target": "wasm32-unknown-unknown",
}
- Add rust-analyzer specific target directory
type --cargo-target-dir
It would be saved on your settings.json
as follows
settings.json
{
"rust-analyzer.cargo.targetDir": true,
}
This prevents rust-analyzer's cargo check and initial build-script and proc-macro building from locking the Cargo.lock at the expense of duplicating build artifacts.
Removing Configuration
Remove Extra Args : type !args
or just !
for shortcut
Removing Test Binary Args : type !--
Removing ENV vars : type !env
Removing Features : type !features
Removing Target : type !target
Removing Cargo Target Dir: type !targetDir
Bonus
Note: This is not part of the plugin but is a cargo related feature that would help you manage your cargo workspace.
1. Using Required features **(Recommended)**
required-features field
This is only relevant for the [[bin]], [bench], [test], and [[example]] sections, it has no effect on [lib].
[lib]
name = "foo" # The name of the target.
path = "src/lib.rs" # The source file of the target.
test = true # Is tested by default.
doctest = true # Documentation examples are tested by default.
bench = true # Is benchmarked by default.
doc = true # Is documented by default.
proc-macro = false # Set to `true` for a proc-macro library.
harness = true # Use libtest harness.
edition = "2015" # The edition of the target.
crate-type = ["lib"] # The crate types to generate.
required-features = [] # Features required to build this target (N/A for lib).
target auto discovery
Note: The list of targets can be configured in the Cargo.toml manifest, often inferred automatically by the directory layout of the source files.
This is the default directory layout for any cargo project.
.
├── Cargo.lock
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── main.rs
│ └── bin/
│ ├── named-executable.rs
│ ├── another-executable.rs
│ └── multi-file-executable/
│ ├── main.rs
│ └── some_module.rs
├── benches/
│ ├── large-input.rs
│ └── multi-file-bench/
│ ├── main.rs
│ └── bench_module.rs
├── examples/
│ ├── simple.rs
│ └── multi-file-example/
│ ├── main.rs
│ └── ex_module.rs
└── tests/
├── some-integration-tests.rs
└── multi-file-test/
├── main.rs
└── test_module.rs
Note: This would only work if you already defined your features on Cargo.toml
Example:
Cargo.toml
[[bin]]
name = "codec"
path = "src/main.rs"
required-features = ["example"]
[features]
default = ["example"]
example = []
Note the difference on using required-features
and features
from rust-analyzer.cargo.features
is that you can specifically choose the specific bin
or lib
you want to require features for , unlike overriding the rust-analyzer.cargo.features which can take effect on all bin
and lib
.
path field can be inferred from the directory layout of the source files.
The path field specifies where the source for the crate is located, relative to the Cargo.toml file.
If not specified, the inferred path is used based on the target name.
Issues
If you find any issues please open an issue on the github repo.
Note: You can set the Cargo Runner: Log Level
to debug on vscode settings to get more info on what is happening.
Support me
If you think I help you in anyway, and want to help me keep doing what I love, the best way to say thank you is to sponsor me on GitHub.