Statically include TOML files. This crate provides a simple way to statically embed data from TOML files at compile time. The provided macro [`static_toml!`] generates the necessary data types to represent the TOML data and assigns the parsed TOML data to a static variable. # Usage Including a TOML file is simple. Here's how to include some text messages defined in a toml: ```toml # messages.toml [info] welcome = "Welcome to our application!" update = "Your data has been updated successfully." [errors] file_not_found = "The requested file could not be found." permission_denied = "You do not have permission to perform this action." ``` ```rust static_toml::static_toml! { static MESSAGES = include_toml!("messages.toml"); } fn main() { // print the message from the toml file println!("{}", MESSAGES.info.welcome); } ``` Accessing the values of nested data structures is done using the dot notation. IDEs capable of expanding proc macros (e.g. VS Code with rust-analyzer or CLion with the Rust plugin) should be able to provide code completion of the included TOML file. Using `cargo doc` on the crate this macro is called will also generate enough documentation to inspect the generated data types. # Syntax The syntax is designed to be intuitive: ```rust,ignore static_toml::static_toml! { [pub] static NAME_1 = include_toml!("file_1.toml"); [pub] static NAME_2 = include_toml!("file_2.toml"); ... [pub] static NAME_N = include_toml!("file_n.toml"); } ``` *Note*: Although this syntax looks like a typical static value assignment via `include_*!`, the data type is omitted. Instead, the data type is generated by the [`static_toml!`] macro call. The `include_toml!` macro is part of the `static_toml!` macro and does not need to be imported separately. In addition to `pub`, other visibilities may also be used. The passed visibility will automatically be applied to both the root module of the generated data types and the static value. For possible values, check [**Visibility and Privacy** in The Rust Reference](https://doc.rust-lang.org/stable/reference/visibility-and-privacy.html). Attributes (including doc comments) are also supported: ``` static_toml::static_toml! { /// doc comments are supported #[allow(missing_docs)] #[derive(Debug)] static EXAMPLE = include_toml!("example.toml"); } ``` The macro attaches doc comments to the generated static value. Derive attributes are propagated through every constructed data type, allowing derive macros like [`Default`] to be used. Other attributes are attached to the root module containing the entry point of the generated data types. # Arrays Arrays in TOML files can have different data types for each item. However, Rust's slices require all elements to be of the same type. This crate aims to simplify access to TOML data, so it avoids using [`Option`] types to handle arrays. The macro analyzes whether all items in an array have *exactly* the same data type. If this is the case, it will generate a fixed-sized slice of that data type, allowing you to iterate over the array and access elements using the `[n]` syntax. If the items in the array do not all have the same data type, the macro will generate a tuple instead. This allows each position in the tuple to have a different data type. In cases where at least one item doesn't match the data type structure of the others, a tuple will be generated. You can still index such a type easily, as tuples may be directly indexed via `.n`. # Configuration You can configure the [`static_toml!`] macro call by applying a `static_toml` attribute to the items you want to configure. - `#[static_toml(prefix = Prefix)]` The macro will add the specified prefix to the beginning of each generated data type. The prefix should be a valid Rust identifier.
- `#[static_toml(suffix = Suffix)]` The macro will add the specified suffix to the end of each generated data type.
- `#[static_toml(root_mod = toml)]` Identifier of the root module that will contain the datatypes for the TOML file. If this is not set the name of the static value will be converted to `snake_case` and used a root mod name.
- `#[static_toml(values_ident = values)]` When generating the value types for arrays, they need their own namespace. By default, this macro will use `values` for naming the modules and data types.
- `#[static_toml(prefer_slices = true)]` This setting determines whether the macro should try to generate fixed size slices when working with arrays. If the setting is set to `false`, the macro will generate tuples for every array. By default, this is set to `true`.
- `#[static_toml(auto_doc = true)]` By default, the macro generates documentation comments, including the file location and contents, enhancing visibility in the generated docs. Setting `auto_doc` to `true` ensures auto-generated documentation is appended after any existing manual comments. Conversely, setting it to `false` disables automatic documentation generation, which may result in the static item lacking documentation comments. This feature is particularly useful for easily accessing TOML contents within rustdoc. You can combine attributes as follows: ```rust static_toml::static_toml! { // all data types will be prefixed, suffixed and derive Default #[derive(Default)] #[static_toml(prefix = Prefix, suffix = Suffix)] static EXAMPLE = include_toml!("example.toml"); } ``` # Using `const` While the `static_toml!` macro is named for its primary functionality of statically including TOML files as `static` variables, it also supports the use of `const` variables. This option is provided to accommodate specific use cases where `const` is necessary. The use of `const` can be crucial in scenarios such as const functions, which can refer to `const` variables but not to `static` variables, and const generics that require `const` values. When deciding between `static` and `const`, it's important to consider the memory usage implications. The `static` keyword is ideal for large TOML files that should only occupy space in the application once, helping to optimize memory usage. In contrast, using `const` could potentially increase the binary size, especially if the same TOML data is reused multiple times. For further details on the `static` keyword in Rust, see the [Rust documentation on `static`](https://doc.rust-lang.org/std/keyword.static.html). To use `const` within the `static_toml!` macro, simply replace `static` with `const` in the macro call. For example: ```rust static_toml::static_toml! { const MESSAGES = include_toml!("messages.toml"); } ``` It's also possible to mix `static` and `const` entries within the same `static_toml!` macro call. However, keep in mind that each identifier must be unique within the same scope. Here's an example of using both `static` and `const` in a single macro call: ```rust static_toml::static_toml! { static MESSAGES = include_toml!("messages.toml"); const EXAMPLE = include_toml!("example.toml"); } ``` # Implementation Details For the specific details, check the documentation for [`static_toml!`].