5 unstable releases

0.11.0 Dec 15, 2021
0.10.2 Nov 3, 2021
0.10.1 Oct 5, 2021
0.10.0 Oct 3, 2021
0.9.0 Jul 22, 2021

#131 in Parser implementations

Download history 248/week @ 2022-03-12 566/week @ 2022-03-19 441/week @ 2022-03-26 276/week @ 2022-04-02 405/week @ 2022-04-09 169/week @ 2022-04-16 206/week @ 2022-04-23 191/week @ 2022-04-30 286/week @ 2022-05-07 552/week @ 2022-05-14 294/week @ 2022-05-21 339/week @ 2022-05-28 473/week @ 2022-06-04 199/week @ 2022-06-11 344/week @ 2022-06-18 274/week @ 2022-06-25

1,391 downloads per month
Used in 13 crates (2 directly)

MIT license

110KB
2.5K SLoC

Doku   crates-badge docs-badge

Doku is a framework for building textual, aesthetic documentation directly from the code; it allows to generate docs for configuration files, HTTP endpoints, and so on.

Say goodbye to stale, hand-written documentation - with Doku, code is the documentation!

Example

[dependencies]
doku = "0.10"
use doku::Document;
use serde::Deserialize;

#[derive(Deserialize, Document)]
struct Config {
    /// Database's engine
    db_engine: DbEngine,

    /// Database's host
    #[doku(example = "localhost")]
    db_host: String,

    /// Database's port
    #[doku(example = "5432")]
    db_port: usize,
}

#[derive(Deserialize, Document)]
enum DbEngine {
    #[serde(rename = "pgsql")]
    PostgreSQL,

    #[serde(rename = "mysql")]
    MySQL,
}

fn main() {
    println!("{}", doku::to_json::<Config>());
}
{
  // Database's engine
  "db_engine": "pgsql" | "mysql",
  // Database's host
  "db_host": "localhost",
  // Database's port
  "db_port": 5432
}

You'll find more examples in ./doku/examples; there's also a documentation at https://docs.rs/doku/.

Contributing

Found a bug, have an idea? Please let us know on GitHub - patches are welcome, too!

If you want to try hacking on Doku, the entry points are:

As for the end-to-end tests, you'll find them inside ./doku/tests.

The way those tests work is that each test-directory contains an input file called input.rs and a set of output files called output.<something>.json.

The input.rs contains a Rust code defining a type called Ty - which can be an enum, a struct, whatever is required for the test - and a top-level comment that specifies which testing-function you want to execute on that type - e.g.:

// run: to_json()

#[derive(Document)]
pub struct Ty {
    foo: Vec<String>,
}

Our procedural macro then finds all of those input.rs-s, reads their // run:, and generates tests resembling:

#[test]
fn test() {
    mod source {
        include!("./path/to/that/input.rs");
    }
    
    to_json::<source::Ty>(/* ... */);
}

That to_json(), and rest of the testing-functions, generate a documentation for Ty and compare the actual input (as generated from the code) to the expected one (as present inside output.<something>.json) - when there's a mismatch, the test fails:

thread '...' panicked at '
Found differences between `...` and `...`:
...

When a test fails, you'll see that next to the output.<something>.json file, there appears a new one, called output.<something>.json.new; this *.new file will contain the test's actual result, and it's up to you to decide if this actual result is the correct one.

If the *.new file looks fine, you can either:

  • manually delete output.<something>.json and then rename output.<something>.json.new to output.<something>.json,

  • or, if you have make and fd installed, you can execute make bless - this will automatically fix all of the tests.

Happy hacking!

License

Licensed under the MIT license.

Dependencies

~0.7–1.4MB
~30K SLoC