DEV Community

Adam.S
Adam.S

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

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)