This specification describes how the command-line utility cargo-specification works.

Cargo-specification

author: David Wong

overview

Building a specification is pretty straight forward. Cargo-spec follows these steps:

  1. parse the specification file with the toml_parser
  2. retrieve the template file
  3. extract the spec comments from all the files listed using comment_parser
  4. render the template
  5. build the spec. We currently support two different formats:

Toml parser

The toml parser expects a manifest specification file that follows the following configuration:

/// A specification file contains a specification, as well as sections of (title, text)
#[derive(Serialize, Deserialize, Debug)]
pub struct Specification {
    /// information about a specification
    pub metadata: Metadata,
    /// configuration of the specification
    pub config: Config,
    /// files to use for the specification's content
    pub sections: HashMap<String, String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
    /// main template file
    pub template: String,
}

/// Metadata about a specification
#[derive(Serialize, Deserialize, Debug)]
pub struct Metadata {
    /// Name of the specification
    pub name: String,
    /// A description
    pub description: Option<String>,
    /// Version of the spec
    pub version: Option<String>,
    /// Authors, if any
    pub authors: Vec<String>,
}

The structures are deserialized using the toml encoding.

Comment parser

Any placeholder in the template will get replaced by comments extracted from code. The specification manifest file contains the list of these files.

parsing is based on the extension of the file:

for each file listed by the specification manifest, we follow these steps:

  1. only print a normal line if it is between //~ spec:startcode and //~spec:endcode statements
  2. if we are within a multi-line comment, we remove the indentation based on the indentation of the first line of the comment
  3. otherwise, we extract what comes after the comment delimiter (note that the result might still have a starting space)
  4. lines starting with //~ spec: are specific instructions:
  5. if we are not seeing an instruction, figure out if:
  6. Finally, extract the specification text. Each ~ at the start of the comment, not including the first one, is converted to a tab. This allows us to write //~~ * for nested list items.
  7. at the end, make sure that every startcode instruction is matched with a endcode instruction
  8. return the result