30 Days of Rust - Day 26
johnnylarner
Posted on June 11, 2023
Good evening everyone, as promised here is my third and final blog this week. I had a lovely trip over the weekend to Brandenburg on my bicycle. The pain in my legs was worth it: we took glorious forest routes and camped at a lovely lake. Back to reality today though with a deeper look into packaging in Rust with cargo
.
Yesterday's questions answered
No questions to answer
Today's open questions
No open questions
We <3 cargo
The keen reader may have noticed that we already looked at some features of cargo
in Day 1's blog . It has also featured in days 5, 7, 10, 13, 14, 19 and 23. It's packed with functionality: the package manager helps with testing, project builds and publishing, documentation and many other things.
Powerful publishing with autodocs and markdown
We already know that cargo
can generate the documentation for any rust project in a locally stored project. This is because HTML is generated from documentation comments
when a project is built using cargo
.
documentation comments
begin with ///
. This is different to the //
of a standard comment. What makes these comments powerful is that they support markdown notation. This means headings and code snippets can be designated for a given function or module which is then rendered into pretty HTML. Where Rust goes one step further is with the documentation testing. Any code snippets you write in your documentation that use an assert
macro are tested when you run cargo test
.
Metamarkdown
There is a third type of comment in Rust: //!
. This is known as a style of doc
comment. There can be used to edit the display HTML outside of the explicit API documentation. For example, if you want to give your crate a meaningful introduction, you'd write //!
followed by some text. This would be rendered at a different position to the usual API code which is nested in with the functions it describes.
User friendly project structure
Often when you write code, the technical implementation can vary from the conceptual structure of the thing your are implementing. This can make your package harder to use: your public APIs are at locations that don't match that position they occupy in the conceptual domain. Also, this can lead to long import statements if the public interface to your code is deeply nested in some structure.
To solve this problem, you can use public re-exports
. This is where you use the use
keyword followed by the name of the module you want to make public. This also impacts how developers see your code in the crates.io documentation.
Another feature of cargo
are so-called workspaces. These offer a way to group multiple projects around a single set of dependencies. You can use the [workspace]
section of your Cargo.toml file to group subdirectories as subprojects. Each will have its own Cargo.toml, but the lock
file will be managed at the common parent level.
The aim here is to ensure that projects you create that are mutually dependent on each other always contain the same, non-breaking dependencies. Nonetheless you have to explicitly add subprojects to another subproject's Cargo.toml for it to be marked as a dependency.
Things to remember about your crates
There are a couple of rules you need to remember when publishing your projects to crates.io
:
- You can't delete old versions. The best you can do is
cargo yank
them, but this will just prevent any external project from using that specific version. - You must specify a licence or a licence file, you can have multiple licences per project.
- Your projects name must be unique on
crates.io
.
Posted on June 11, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.