Expand description

The doc file generator is used to write example JSON and TypeScript definitions for the docs of return values of API endpoints.

This is done by writing .json and .ts files that can be discovered by the #generated_doc attribute macro that is used by API endpoints.

To make this process more convenient, two macros are provided:

  • example! (proc macro defined in the doc_macros crate)
  • doc! (declarative macro defined in this file)

example!

Accepts a struct or enum literal, such as

example!(SomeStruct {
    first_field,
    second_field: 1234,
});

and implements the Example trait for the given type:

impl Example for SomeStruct {
    fn example() -> Self {
        Self {
            first_field: Example::example(),
            second_field: 1234,
        }
    }
}

As can be seen in the code above, you can leave out the value of any field to use its Example implementation.

The Example trait is used for the doc! macro as explained below.

doc!

Writes the JSON and TypeScript files used for API endpoint docs.

This macro can be used in two primary ways:

  • With a struct/enum literal
  • With a type and expression

With a struct/enum literal, the doc! macro generates an Example implementation for the type using the example! macro and then uses it to write the JSON docs. (The TypeScript definition is generated with the ts_rs::TS trait)

doc!(SomeStruct {
    first_field,
    second_field: 1234,
});

In addition to the impl Example for SomeStruct, it will serialize <SomeStruct as Example>::example() to JSON and write it to generated-docs/SomeStruct.json, as well as <SomeStruct as TS>::inline() to generated-docs/SomeStruct.ts.

Note that because it uses the example! macro, you can leave out values for fields the same way.

The struct/enum literal can be prepended with T, Option, or Vec, in order to generate docs for the given type (T), Option of the given type (Opt), or Vec of the given type (Vec). Note that they must be in the order T, Option, Vec, though you can leave any (or all) of them out.

For example,

doc!(
    T,
    Vec,
    SomeStruct {
        first_field,
        second_field: 1234,
    }
);

will create docs for SomeStruct and Vec<SomeStruct>.

With a type and expression, the doc! macro simply uses the expression to write the JSON docs for the given type without involving the Example trait or example! macro.

doc!(
    Vec<SomeStruct>,
    vec![
        SomeStruct {
            first_field: Example::example(),
            second_field: 2,
        },
        SomeStruct {
            first_field: 3,
            second_field: 4,
        },
    ]
);

Note that since this method doesn’t use the example! macro, leaving out field values is an error. If we want to use the Example trait here, we need to explicitly call Example::example() or the ex() function which is just a shortcut for Example::example().

This method is mainly useful for external/std types. For example, we cannot write Uuid as a struct literal because it has private fields, or bool because it’s a primitive type.

Modules

Functions