cli_lib
A workspace with a console crate and a library crate, the path dependency and the call between them already written.
What it generates
<name>_cli— a binary crate that depends on the library by path and calls its example method<name>_lib— a library crate holding one example method and the unit test for it
Source: cli_lib in the templates repository.
cargo new cannot produce this layout: --bin and --lib are mutually
exclusive. The layout matters because a binary target cannot be
integration-tested —
tests/ links against a library target, so code in main.rs is reachable only
from unit tests in that same file. Putting the logic in a
library crate and
leaving the binary as a caller is the usual way around it.
The crates sit in a
workspace under
crates/. The binary declares the library as a path dependency and calls it
from main.
Three settings it gets right, each easy to miss when writing a workspace by hand:
resolver = "3" — a virtual manifest without it falls back to resolver 1, and
cargo emits a warning on every build.
[workspace.package] — version and edition are declared once and taken by
each crate with version.workspace = true, rather than copied.
Underscores in crate names — hyphens are valid in a package name but not in a
Rust identifier, so a hyphenated package is spelled one way in Cargo.toml and
another in use.
Generating it
Crate names default to the project name
cargo generate --git https://github.com/NGDeveloper125/rusty-yellow-pages-templates cli_lib --name inventory_tool
Or name either crate yourself
cargo generate --git https://github.com/NGDeveloper125/rusty-yellow-pages-templates cli_lib --name shop -d cli_name=shop_console -d lib_name=shop_engine
Installing cargo-generate
cargo-generate is a separate subcommand, installed once.
cargo install cargo-generate