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 configurationaction
(Array of 'String's): List of actions this config can takeString
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!
Generating Markdown
Depending on your case you can interact with TypeDescription
s in multiple ways.
If you are given a JSON formatted type description file, then you can use the CLI for further processing. (This may be the case if you are using someone else's project).
If you have some Rust types and want to generate markdown directly from their
TypeDescription
then you might be best served with the library.
Using the CLI
The preferred way of interacting with the CLI is to use the type_description
binary.
It can be invoked in the following ways:
- With the nix package manager (flakes enabled):
nix run github:TheNeikos/type_description
- With cargo:
cargo install type_description
- Directly from source:
git clone https://github.com/TheNeikos/type_description && cd type_description && cargo run -F bin
Either way you have installed it. You can now generate markdown from it by sending it to standard input.
E.g.:
- Using nix:
cat <your description file> | nix run github:TheNeikos/type_description
- After installing it:
curl example.com/some_type_description | type_description
- Building from source:
curl example.com/some_type_description | cargo run -F bin
Using the library
Rendering a TypeDescription
to markdown can be done with the
type_description::render::render_to_markdown
method.
extern crate type_description; fn main() { use type_description::AsTypeDescription; let ty_desc = std::collections::HashMap::<String, f64>::as_type_description(); let markdown: String = type_description::render::render_to_markdown(&ty_desc).expect("Could not render to markdown"); println!("{}", markdown); }
You can then use a markdown to HTML processor to generate HTML, or maybe print
it to the terminal with the termimad
crate.