DEV Community

Cover image for 30 Days of Rust - Day 26
johnnylarner
johnnylarner

Posted on

30 Days of Rust - Day 26

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:

  1. 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.
  2. You must specify a licence or a licence file, you can have multiple licences per project.
  3. Your projects name must be unique on crates.io.

Top comments (0)