A cargo plugin for managing quick, disposable, local, and IDE-friendly Rust experiments with arbitrary dependencies.
cargo-lab is a tool for setting up, running, and managing collections of
one-off experiments in rust.
Like the Rust Playground, this tool aims to make
it as fast and painless as possible to run some rust code. However, cargo-lab
makes some different choices - it lets you experiment:
- on your machine;
- with your normal dev tooling (including your IDE's autocomplete, typechecking, linting, ...);
- with arbitrary dependencies† and features;
- in a completely standard, tooling-friendly cargo project;
- with a persistent collection of all your experiments.
†WARNING: This is not a sandbox.
Don't run untrusted code or dependencies without protection.
A cargo lab-managed "lab" is just a local cargo project; the same security
principles apply. Running a malicious lab script or dependency - or even just
building a malicious dependency - is
exactly
as
dangerous
here as it would be in any other cargo project.
This program is designed to run as a cargo subcommand, and can be installed via
cargo install cargo-lab. (To setup tab-completion in your shell, see
cargo lab completions --help).
You can then set up a new "lab" project:
# create or initialize a lab project
mkdir new-lab
cargo lab init ./new-lab
# Creates a new script, setting up the file and adding it to Cargo.toml
cargo lab new my-script-name dep1 -F dep1/feature
# Add dependencies and activate features for a script
cargo lab inject my-script-name dep1 dep2 -F dep1/featurename -F dep2/featurename
# Run a script (with all dependencies automatically activated)
cargo lab run my-script-nameA "cargo laboratory" is cargo project with lots of one-off experiments (we'll
call these "scripts"), all with their own arbitrary dependencies. You can create
a new laboratory project by running cargo lab init $path where $path is an
empty or new directory.
$ cargo lab init ./labdir
Initializing project directory ...
Creating first script ...
success: Created minimal script at: src/my_first_experiment.rs
success: Lab initialized in directory '/path/to/labdir'
Tips:
1) To enable tab-completion, see `cargo lab completions --help`
2) To easily run experiments from any working directory, set
`CARGO_LAB_MANIFEST_DIR=/path/to/labdir`
or use the `--manifest-path` flag
(`cargo lab --manifest-path=/path/to/labdir`).
3) To alias this command to something shorter, prefer a shell alias
(e.g., `alias clb="cargo lab"`) over a cargo alias (in `.cargo/config.toml`),
as tab-completion does not currently support cargo aliases.
This will create a completely normal cargo project and Cargo.toml manifest that the dev tooling of your choice should happily work with:
$ cd labdir
$ tree .
./
├── Cargo.toml
├── src
│ └── my_first_experiment.rs
└── templates
├── bare.rs.template
├── basic.rs.template
├── clap.rs.template
└── clap_subcmd.rs.template
Each script managed by cargo-lab will have an entry like this in Cargo.toml:
[[bin]]
name = "my-first-experiment"
path = "./src/my_first_experiment.rs"
required-features = ["dep1", "dep2", "dep3/feature"]Note that you can (and should) edit the generated Cargo.toml if you want, and
cargo lab should continue to work normally. (If something gets messed up, try
running cargo check and cargo lab check to detect config issues.)
When executing these scripts, cargo lab run takes care of automatically
activating all the features listed in required-features (cargo run requires
them all to be listed manually):
# this "cargo lab run" command:
cargo lab run my-first-experiment
# is the same as running:
cargo run --bin my-first-script --features 'dep1,dep2,dep3/feature'(Use cargo lab --help and cargo lab [subcmd] --help to see complete docs.)
cargo install --locked cargo-labwill build and install the latest stable version from crates.io and make thecargo labsubcommand available.cargo lab completions --helpwill print out the tab-completion setup steps for supported shells (fish, bash, zsh).cargo lab init (lab path)will create a new lab project.
After creating a project, you can set the CARGO_LAB_MANIFEST_PATH environment
variable to quickly run your experiments from any working dir.
cargo lab quick [deps] [-F (features)] [--edit]: create a new script with autogenerated namecargo lab new (SCRIPTNAME) [deps] [-F (features)] [--edit]: create a new script with a chosen name
Note that if tab-completion has been enabled in your shell, all script names (in addition to subcommands, flags, and other CLI arguments) can be autocompleted in these commands.
cargo lab run (SCRIPT) [args ...]: run a script (unlikecargo run --bin, this automatically activates all required features)cargo lab edit (SCRIPT): open the script in your editor (requires that theeditor-cmdfield to be set in the[package.metadata.cargo-lab]tableCargo.toml)cargo lab inject (SCRIPT) [deps] [-F features]- add dependencies and activate features for an existing scriptcargo lab rename (SCRIPT) (NEW_NAME)- rename a script
Let's say I want to experiment with the proc-macro2 crate. First I'll create a
new script and ask for it to be opened in my IDE immediately. (Note the
cargo lab quick command automatically generates a name for the script so I
don't have to think of one myself.)
$ cargo lab quick proc-macro2 --edit
Generated script name: try-proc-macro2
running:
$ cargo add --optional proc-macro2
Updating crates.io index
Adding proc-macro2 v1.0.106 to optional dependencies
Features:
+ proc-macro
- nightly
- span-locations
Adding feature `proc-macro2`
Updating crates.io index
Locking 2 packages to latest Rust 1.94.1 compatible versions
success: Created minimal script at: src/try_proc_macro2.rs
Updated Cargo.toml:
19a20,24
> [[bin]]
> name = "try-proc-macro2"
> path = "src/try_proc_macro2.rs"
> required-features = ["proc-macro2"]Then, let's say I also decide to use the syn and quote crates in this
experiment - and want to activate syn's "parsing" feature. I can inject
these into the script later.
$ cargo lab inject try-proc-macro2 syn quote --feature syn/parsing
running: "$ cargo add --optional syn quote"
Updating crates.io index
[...]
Updating features for "try-proc-macro2" in Cargo.toml:
< required-features = ["proc-macro2"]
---
> required-features = ["proc-macro2", "syn", "quote", "syn/parsing"]Now, I can make my changes and run it.
$ # ... make changes ...
$ cargo lab run try-proc-macro2
my experiment's output goes hereInstructions for setting up tab completions for various shells can displayed by
running cargo lab completions --help. Fish, Bash, and ZSH are all supported;
other shells supported by clap may work but have not been tested.
If you experience issues with tab completions, they may be due to conflicts with
other cargo plugins or even cargo itself. One workaround is to call the
executable directly (spelled "cargo-lab" with a hyphen, one word) instead of
through cargo ("cargo lab" with a space in the middle, two words).
cargo lab stores configuration lab's Cargo.toml in the
[package.metadata.cargo-lab] table. Note that this tool won't make any
modifications to your project unless this table is present.
[package.metadata.cargo-lab]
# cargo-lab won't make changes to any project unless
# unless this field exists and is set to "true":
enabled = true
# Optional command to launch an editor when requested with
# `--edit` flag or `edit` subcommand.
editor-cmd = ["rustrover"]- for me, rust is a very IDE-driven language, so even if I'm working with a one-off experiment, I'd really like to have autocompletion, cargo fmt, clippy, pop-up docs, etc. available;
- Quick one-off scripts are the next best alternative to the live REPL-/jupyter- driven exploration that you can do in interpreted languages;
- it's nice to run experiments locally and maybe even keep them in a repo in case you want to refer back to them later; and finally
- it's a bit excessive to create entire new cargo projects for each one-off experiment.
- The Official Rust Playground is wonderful and
maybe the quickest way to write some rust code. But what if you want to try
out a dependency that's not in top 100, or use your local IDE's
autocompletion, or even just work offline?
- There is also Rust explorer, also web based but supports the top 10k dependencies, not just top 100.
- There is (was?) funding to improve web-based rust "lab" ecosystem, which is great.
- single file cargo scripts are also a great idea, but don't yet have IDE support.
-
evcxris an insanely impressive REPL for rust (which should not be even possible, but it actually works) - A normal crate with lots of
[[bin]]entries also works ok - this project used to be my personal lab repository, which then evolved anxtaskto help manage the dependencies, which then turned into this standalone tool. - Lutetium-Vanadium/cargo-playground, Actually seems very similar to this project, but unfortunately I didn't stumble on it it until after I finished this one.
- License: This project is provided under the MIT License.
- 3rd party sources: The source code in the
src/vendor_cargodirectory is vendored from the cargo project and used under the MIT license. - Copyrightability: all first-party material in this repository was written solely by (and for) its human authors. It does not contain, nor was it derived from, LLM or other generative "AI" output.
This software provides a plugin for the cargo command-line tool. It is not
a product of or otherwise affiliated with the
Cargo project.