1mod field_path;
2mod format;
3mod schema;
4
5pub use field_path::FieldPath;
6use schemars::JsonSchema;
7use serde::Serialize;
8pub use toml_scaffold_macros::TomlScaffold;
9
10pub trait TomlScaffold: Serialize + JsonSchema {
12 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
14 std::collections::HashMap::new()
15 }
16
17 fn to_scaffold(&self) -> Result<String, toml::ser::Error> {
19 let value = toml::Value::try_from(&self)?;
21
22 let schema = schemars::schema_for!(Self);
24 let mut schema_info = schema::extract_schema_info(&schema, &FieldPath::new());
25
26 schema_info.formats.extend(Self::format_preferences());
28
29 let result = format::format_with_comments(
31 &value,
32 &schema_info.comments,
33 &schema_info.all_fields,
34 &schema_info.optional_fields,
35 &schema_info.formats,
36 &FieldPath::new(),
37 );
38
39 Ok(format!("{}\n", result.trim_end()))
41 }
42}
43
44macro_rules! impl_toml_scaffold_empty {
46 ($($ty:ty),* $(,)?) => {
47 $(
48 impl TomlScaffold for $ty {
49 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
50 std::collections::HashMap::new()
51 }
52 }
53 )*
54 };
55}
56
57impl_toml_scaffold_empty!(
59 String, &str, bool, char, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32,
60 f64,
61);
62
63impl_toml_scaffold_empty!(serde_json::Value, std::path::PathBuf,);
65
66impl<T: TomlScaffold> TomlScaffold for Vec<T> {
68 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
69 std::collections::HashMap::new()
70 }
71}
72
73impl<T: TomlScaffold> TomlScaffold for Option<T> {
74 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
75 std::collections::HashMap::new()
76 }
77}
78
79impl<K: Serialize + JsonSchema, V: TomlScaffold> TomlScaffold for std::collections::HashMap<K, V> {
80 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
81 std::collections::HashMap::new()
82 }
83}
84
85impl<K: Serialize + JsonSchema, V: TomlScaffold> TomlScaffold for std::collections::BTreeMap<K, V> {
86 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
87 std::collections::HashMap::new()
88 }
89}
90
91impl<T: TomlScaffold> TomlScaffold for std::collections::HashSet<T> {
92 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
93 std::collections::HashMap::new()
94 }
95}
96
97impl<T: TomlScaffold> TomlScaffold for std::collections::BTreeSet<T> {
98 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
99 std::collections::HashMap::new()
100 }
101}
102
103impl<T: TomlScaffold> TomlScaffold for Box<T> {
104 fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
105 std::collections::HashMap::new()
106 }
107}