An open API service indexing awesome lists of open source software.

https://github.com/crambl/descriptive_toml_derive

Procedural derive macro for serializing a struct into a TOML template with field descriptions that is easily edited and deserialized.
https://github.com/crambl/descriptive_toml_derive

derive-macro macros-rust procedural-macro

Last synced: 2 months ago
JSON representation

Procedural derive macro for serializing a struct into a TOML template with field descriptions that is easily edited and deserialized.

Awesome Lists containing this project

README

        

![Crates.io](https://img.shields.io/crates/d/descriptive_toml_derive)
![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/crambl/descriptive_toml_derive)

# Description
Procedural derive macro for serializing a struct into a TOML template with field descriptions that is easily edited and deserialized.

Nested structs are not currently supported.

# Purpose
Make it easy to write a struct that defines a `TOML` template for optional configuration of an executable. Once the struct is deserialized with the derive macro implemented `to_string_pretty_toml()` function, it can be written to a (TOML) file, the file should be understandable without knowing any details of the binary. Deserializing the produced TOML file with no edits produceses the original struct with all optional fields `None`. Editing the produced TOML file will then deserialize into the original struct with those edited values.

# Table of Contents
- [Description](#description)
- [Purpose](#purpose)
- [Table of Contents](#table-of-contents)
- [Guide](#guide)
- [What is derived?](#what-is-derived)
- [Example use in fastPASTA](#example-use-in-fastpasta)
- [Implementing](#implementing)
- [Serializing](#serializing)
- [Deserializing](#deserializing)

# Guide

## What is derived?
A `pub trait` named `TomlConfig` with a single function with the signature: `fn to_string_pretty_toml(&self) -> String`

```rust
pub trait TomlConfig {
fn to_string_pretty_toml(&self) -> String;
}
```

## Example use in fastPASTA
This macro was originally made for use in the [fastPASTA](https://crates.io/crates/fastpasta) crate.
The example is based on how the macro is used in `fastPASTA`.

### Implementing
The struct `CustomChecks` is implemented like this:

```rust
use descriptive_toml_derive::TomlConfig;
use serde_derive::{Deserialize, Serialize};

pub trait TomlConfig {
fn to_string_pretty_toml(&self) -> String;
}

// Deriving the `TomlConfig` macro which implements the `TomlConfig` trait.
#[derive(TomlConfig, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CustomChecks {
// Use the `description` field attribute of the macro
#[description = "Number of CRU Data Packets expected in the data"]
// Use the `example` field attribute of the macro to show some example values
#[example = "20, 500532"]
cdps: Option,

#[description = "Number of Physics (PhT) Triggers expected in the data"]
#[example = "0, 10"]
triggers_pht: Option,

#[description = "Legal Chip ordering for Outer Barrel (ML/OL). Needs to be a list of two lists of 7 chip IDs"]
#[example = "[[0, 1, 2, 3, 4, 5, 6], [8, 9, 10, 11, 12, 13, 14]]"]
chip_orders_ob: Option<(Vec, Vec)>,
}
```
### Serializing

The template file is generated e.g. like this.
```rust
let toml = CustomChecks::default().to_string_pretty_toml();
std::fs::write("custom_checks.toml", toml).unwrap();
```
The contents of "custom_checks.toml" is now:
```toml
# Number of CRU Data Packets expected in the data
# Example: 20, 500532
#cdps = None [ u32 ] # (Uncomment and set to enable this check)

# Number of Physics (PhT) Triggers expected in the data
# Example: 0, 10
#triggers_pht = None [ u32 ] # (Uncomment and set to enable this check)

# Legal Chip ordering for Outer Barrel (ML/OL). Needs to be a list of two lists of 7 chip IDs
# Example: [[0, 1, 2, 3, 4, 5, 6], [8, 9, 10, 11, 12, 13, 14]]
#chip_orders_ob = None [ (Vec < u8 >, Vec < u8 >) ] # (Uncomment and set to enable this check)
```
Editing all the fields to contain `Some` values could look like this:
```toml
# Number of CRU Data Packets expected in the data
# Example: 20, 500532
cdps = 20

# Number of Physics (PhT) Triggers expected in the data
# Example: 0, 10
triggers_pht = 0

# Legal Chip ordering for Outer Barrel (ML/OL). Needs to be a list of two lists of 7 chip IDs
# Example: [[0, 1, 2, 3, 4, 5, 6], [8, 9, 10, 11, 12, 13, 14]]
chip_orders_ob = [[0, 1, 2, 3, 4, 5, 6], [8, 9, 10, 11, 12, 13, 14]]
```
### Deserializing

Deserializing from a TOML file is the same method as with any other TOML file, using `serde_derive`:
```rust
let toml = std::fs::read_to_string("custom_checks.toml").unwrap();
let custom_checks = toml::from_str(&toml).unwrap();
```

A user that is already familiar with the configuration file might simply write
```toml
cdps = 10
```
And input it to the binary. Which would deserialize into a struct with the `cdps` field containing `Some(10)`, and the rest of the fields are `None`.