DEV Community

Adam.S
Adam.S

Posted on • Edited on • Originally published at bas-man.dev

1 1

Rust: Documenting your Code

Hi.

As with all projects. It's important to create documentation. This is, as we know, very important when creating code. When we come back to a project after a break, or if someone new takes over. Documentation will help you remember or learn what the code does. The thinking that was behind certain decisions.

Here I will be documenting some examples of what I have learned. This is not to be an extensive look.

Resources

As with everything new. I started with some research. I found this really good article. I strongly recommend you take a look at the article.

There is also the standard docs

I will only be concerning myself wth the dns module I have been creating.

First let's generate the documentation with what I have already.

cargo doc && cargo doc --open
Enter fullscreen mode Exit fullscreen mode

Then navigate to the dns module and then spf.
dns spf 1

Basic excluding of internal functions and modules

In the above image we can see a list of functions. These functions are internal implementation details. And users of the module do not need to be aware of these. Let's hide these functions from rust's documentation system.

For this we use the #[doc(hidden)] instruction.

For each function we need to add this instruction just above the function declaration. This is done within src/dns/spf/mod.rs.

#[doc(hidden)]
// Check if the initial character in the string `record` matches `c`
// If they do no match then return the initial character
// if c matches first character of record, we can `+`, a blank modiifer equates to `+`
fn return_and_remove_qualifier(record: &str, c: char) -> (char, &str) {
Enter fullscreen mode Exit fullscreen mode
#[doc(hidden)]
fn remove_qualifier(record: &str) -> &str {
Enter fullscreen mode Exit fullscreen mode
#[doc(hidden)]
fn capture_matches(
    pattern: Regex,
Enter fullscreen mode Exit fullscreen mode

We have to regenerate the documentation if we want to see the changes

cargo doc
Enter fullscreen mode Exit fullscreen mode

Then we can reload the documentation page.

We now have a cleaner page with the internal functions removed.
dns spf 2

You can use the #[doc(hidden)] to also hide the test modules from documentation.

#[doc(hidden)]
mod spf_a_mechanism_test;
#[doc(hidden)]
mod spf_mx_mechanism_test;
#[doc(hidden)]
mod spf_test;
Enter fullscreen mode Exit fullscreen mode

Adding module level documentation

If you look closely at the new page. You will notice there is no information about what this module does. We need to add some module level documentation.

At the the top of mod.rs I will add.

//! This module creates an object that contains a deconstructed SPF DNS record.
Enter fullscreen mode Exit fullscreen mode

We then regenerate the documentation again. (skipped from here on out)
dns spf 3

Documenting Functions and Methods

Let's move to documenting some of the functions associated with the Spf struct

Documenting the Spf::new() Method.
spf-new-doc-sample

An important thing to note here is that the code between the backticks is actually tested when you run cargo test.

Note: The above example will not actually work. If you are looking for a real example checkout the next article



Documenting the parse() Method.

/// Parse the contents of `source` and populate the internal structure of `Spf`
pub fn parse(&mut self) {
Enter fullscreen mode Exit fullscreen mode

This now gives us.
dns spf 4

Linking within the documentation

I would refer you to this stack overflow link as a starter.

Here is a small example.

#[derive(Debug, Clone)]
pub enum MechanismKind {
    /// Represents a Mechanism of type include:
    Include,
    /// Represents a Mechanism of type redirect=
    Redirect,
}

impl MechanismKind {
    /// Returns `true` if the mechanism is [`Include`](MechanismKind::Include).
    pub fn is_include(&self) -> bool {
        matches!(self, Self::Include)
    }
    /// Returns `true` if the mechanism is [`Redirect`](MechanismKind::Redirect).
    pub fn is_redirect(&self) -> bool {
        matches!(self, Self::Redirect)
    }
}
Enter fullscreen mode Exit fullscreen mode

Like Markdown we use [label](link) the difference is that the link is written as if we are using it in actual rust code MechanismKind::Include

dns spf 5
Clicking on the Include for the Returns 'true' if mechanism is Include links you up to the definition of Include under Variants.

That's it for today. I will update this article if I find new interesting things.

Hope this helps.

Top comments (0)

Bump.sh

Hate writing docs?

Hate undocumented APIs even more?

Bump.sh generates an always up-to-date API reference site for REST and Event-Driven Architectures.

Plug it in your CI. It fetches your OpenAPI and AsyncAPI (GraphQL pending) spec files, and even generates a diff. Gather all of your API docs in a single source of truth.

Try it for free

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay