Binary for my library

I have a library, published on crates.io, with the standard src/lib.rs layout. Nothing fancy. Now I want to make an executable that can leverage my library to convert the file to JSON and say pretty print it to terminal.

$ mybin file.nzb --json
[...]

So here comes my questions:

  • Can I have both in my repo?
  • What's the idiomatic approach?
  • I'll likely have binary specific dependencies (say clap) which will be entirely useless for libraries

touch src/main.rs

That's it, now you have a second, binary, crate in your package, that implicitly depends on the library part.

If you want more than one, each *.rs file directly in src/bin/ becomes a new binary crate.

For this case, I recommend using src/bin/*.rs even if you have only one binary crate. It avoids any possible confusion over which crate a module file belongs to.

Unfortunately, there is no way to directly have dependencies only for the binaries. You can define a feature which is declared as required-features for the binary and enable the relevant dependencies, but then people wishing to install it will have to write cargo install nzb-rs --features mybin.

It is often more practical to have a separate package for binaries, due to this limitation. In your repo, these can be part of a workspace, but that only affects development, not the published form.

1 Like

So the best approach here is setting up a workspace? Additionally, I'm not sure I understand the publishing part. How should I publish them?

So the best approach here is setting up a workspace?

If you decide to have multiple packages, then you should set up a workspace for them, for your convenience.

How should I publish them?

Every package is published separately. Every package has its own name, version number, and dependencies (so, your CLI package would depend on your library package).

Currently, that means literally a cargo publish command per package, but in the future, or with unstable features you will be able to publish multiple packages in one command.