Expand description
This crate provides the TomlExample trait and an accompanying derive macro.
Deriving TomlExample on a struct will generate functions toml_example(), to_toml_example(file_name) for generating toml example content.
The following code shows how toml-example can be used.
use toml_example::TomlExample;
/// Config is to arrange something or change the controls on a computer or other device
/// so that it can be used in a particular way
#[derive(TomlExample)]
struct Config {
/// Config.a should be a number
a: usize,
/// Config.b should be a string
b: String,
/// Optional Config.c is a number
c: Option<usize>,
/// Config.d is a list of number
d: Vec<usize>,
#[toml_example(default =7)]
e: usize,
/// Config.f should be a string
#[toml_example(default = "seven")]
f: String,
}
assert_eq!( Config::toml_example(),
r#"# Config is to arrange something or change the controls on a computer or other device
# so that it can be used in a particular way
# Config.a should be a number
a = 0
# Config.b should be a string
b = ""
# Optional Config.c is a number
# c = 0
# Config.d is a list of number
d = [ 0, ]
e = 7
# Config.f should be a string
f = "seven"
"#);Also, toml-example will use #[serde(default)], #[serde(default = "default_fn")] for the
example value.
With nesting structure, #[toml_example(nesting)] should set on the field as following
example.
use std::collections::HashMap;
use toml_example::TomlExample;
/// Service with specific port
#[derive(TomlExample)]
struct Service {
/// port should be a number
#[toml_example(default = 80)]
port: usize,
}
#[derive(TomlExample)]
#[allow(dead_code)]
struct Node {
/// Services are running in the node
#[toml_example(default = http, nesting)]
services: HashMap<String, Service>,
}
assert_eq!(Node::toml_example(),
r#"# Services are running in the node
# Service with specific port
[services.http]
# port should be a number
port = 80
"#);Flattened items are supported as well.
use toml_example::TomlExample;
#[derive(TomlExample)]
struct ItemWrapper {
#[toml_example(flatten, nesting)]
item: Item,
}
#[derive(TomlExample)]
struct Item {
value: String,
}
assert_eq!(ItemWrapper::toml_example(), Item::toml_example());Flattening works with maps too!
use serde::Deserialize;
use toml_example::TomlExample;
#[derive(TomlExample, Deserialize)]
struct MainConfig {
#[serde(flatten)]
#[toml_example(nesting)]
nested: HashMap<String, ConfigItem>,
}
#[derive(TomlExample, Deserialize)]
struct ConfigItem {
#[toml_example(default = false)]
enabled: bool,
}
let example = MainConfig::toml_example();
assert!(toml::from_str::<MainConfig>(&example).is_ok());
assert_eq!(example, r#"[example]
enabled = false
"#);The fields of a struct can inherit their defaults from the parent struct when the
#[toml_example(default)], #[serde(default)] or #[serde(default = "default_fn")]
attribute is set as an outer attribute of the parent struct:
use serde::Serialize;
use toml_example::TomlExample;
#[derive(TomlExample, Serialize)]
#[serde(default)]
struct Config {
/// Name of the theme to use
theme: String,
}
impl Default for Config {
fn default() -> Self {
Self {
theme: String::from("Dark"),
}
}
}
assert_eq!(Config::toml_example(),
r#"# Name of the theme to use
theme = "Dark"
"#);If you want an optional field become a required field in example,
place the #[toml_example(require)] on the field.
If you want to skip some field you can use #[toml_example(skip)],
the #[serde(skip)], #[serde(skip_deserializing)] also works.
use toml_example::TomlExample;
#[derive(TomlExample)]
struct Config {
/// Config.a is an optional number
#[toml_example(require)]
a: Option<usize>,
/// Config.b is an optional string
#[toml_example(require)]
b: Option<String>,
#[toml_example(require, default = "third")]
c: Option<String>,
#[toml_example(skip)]
d: usize,
}
assert_eq!(Config::toml_example(),
r#"# Config.a is an optional number
a = 0
# Config.b is an optional string
b = ""
c = "third"
"#)You can also use fieldless enums, but you have to annotate them with #[toml_example(enum)] or
#[toml_example(is_enum)] if you mind the keyword highlight you likely get when writing
“enum”.
When annotating a field with #[toml_example(default)] it will use the
Debug implementation.
However for non-TOML data types like enums, this does not work as the value needs to be treated
as a string in TOML. The #[toml_example(enum)] attribute just adds the needed quotes around
the Debug implementation and can be omitted if a custom
Debug already includes those.
use toml_example::TomlExample;
#[derive(TomlExample)]
struct Config {
/// Config.priority is an enum
#[toml_example(default, enum)]
priority: Priority,
}
#[derive(Debug, Default)]
enum Priority {
#[default]
Important,
Trivial,
}
assert_eq!(Config::toml_example(),
r#"# Config.priority is an enum
priority = "Important"
"#)Re-exports§
pub use traits::*;