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


Then navigate to the dns module and then spf.

## 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) {

#[doc(hidden)]
fn remove_qualifier(record: &str) -> &str {

#[doc(hidden)]
fn capture_matches(
pattern: Regex,


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

cargo doc


Then we can reload the documentation page.

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

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;


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.


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

## Documenting Functions and Methods

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

Documenting the Spf::new() Method.

impl Spf {
/// Create a new Spf with the provided str
///
/// # Example
///
/// 
/// let spf = Spf::new("v=spf1 redirect=_spf.example.com");
/// 
///
pub fn new(str: &String) -> Self {


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 here

Documenting the parse() Method.

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


This now gives us.

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)
}
}


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

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.