Introduction

The type_description crate is the basic block to allow for discovery of configuration options in your Rust projects.

It allows for self-describing types in your project, and an easy way to export them. This description can then be manipulated like any other data, allow for processing into for example Markdown or a questionnaire.

An example would be the following:

//
//   This Source Code Form is subject to the terms of the Mozilla Public
//   License, v. 2.0. If a copy of the MPL was not distributed with this
//   file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
extern crate type_description;
extern crate serde_json;

use type_description::{AsTypeDescription, TypeDescription};

fn main() {


#[derive(TypeDescription)]
struct MyConfiguration {
    /// The name of this configuration
    name: String,

    /// List of actions this config can take
    action: Vec<String>,
}

assert_eq!(serde_json::to_string_pretty(&MyConfiguration::as_type_description()).unwrap(), r#"
{
  "name": "MyConfiguration",
  "kind": {
    "Struct": [
      {
        "name": "name",
        "doc": "The name of this configuration",
        "kind": {
          "name": "String",
          "kind": "String",
          "doc": "An UTF-8 string"
        }
      },
      {
        "name": "action",
        "doc": "List of actions this config can take",
        "kind": {
          "name": "Array of 'String's",
          "kind": {
            "Array": {
              "name": "String",
              "kind": "String",
              "doc": "An UTF-8 string"
            }
          },
          "doc": null
        }
      }
    ]
  },
  "doc": null
}
"#.trim())

}

This would then output a datastructure (if rendered as JSON) like this:

//
//   This Source Code Form is subject to the terms of the Mozilla Public
//   License, v. 2.0. If a copy of the MPL was not distributed with this
//   file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
extern crate type_description;
extern crate serde_json;

use type_description::{AsTypeDescription, TypeDescription};

fn main() {


#[derive(TypeDescription)]
struct MyConfiguration {
    /// The name of this configuration
    name: String,

    /// List of actions this config can take
    action: Vec<String>,
}

assert_eq!(serde_json::to_string_pretty(&MyConfiguration::as_type_description()).unwrap(), r#"
{
  "name": "MyConfiguration",
  "kind": {
    "Struct": [
      {
        "name": "name",
        "doc": "The name of this configuration",
        "kind": {
          "name": "String",
          "kind": "String",
          "doc": "An UTF-8 string"
        }
      },
      {
        "name": "action",
        "doc": "List of actions this config can take",
        "kind": {
          "name": "Array of 'String's",
          "kind": {
            "Array": {
              "name": "String",
              "kind": "String",
              "doc": "An UTF-8 string"
            }
          },
          "doc": null
        }
      }
    ]
  },
  "doc": null
}
"#.trim())

}

As you can see, not only is the struct itself described, but also all of its constituents as well as the documentation you have provided.

If you want to, you could use the binary provided by the type_description crate to transform it into markdown!

This would output something akin to:

MyConfiguration

Fields:

  • name (String): The name of this configuration
  • action (Array of 'String's): List of actions this config can take

String

An UTF-8 string

Array of 'String's

Array Elements of String

If this sounds intruiging, read on and find out how it can be used!