mod field_path;
mod format;
mod schema;
pub use field_path::FieldPath;
use schemars::JsonSchema;
use serde::Serialize;
pub use toml_scaffold_macros::TomlScaffold;
pub trait TomlScaffold: Serialize + JsonSchema {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
fn to_scaffold(&self) -> Result<String, toml::ser::Error> {
let value = toml::Value::try_from(&self)?;
let schema = schemars::schema_for!(Self);
let mut schema_info = schema::extract_schema_info(&schema, &FieldPath::new());
schema_info.formats.extend(Self::format_preferences());
let result = format::format_with_comments(
&value,
&schema_info.comments,
&schema_info.all_fields,
&schema_info.optional_fields,
&schema_info.formats,
&FieldPath::new(),
);
Ok(format!("{}\n", result.trim_end()))
}
}
macro_rules! impl_toml_scaffold_empty {
($($ty:ty),* $(,)?) => {
$(
impl TomlScaffold for $ty {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
)*
};
}
impl_toml_scaffold_empty!(
String, &str, bool, char, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32,
f64,
);
impl_toml_scaffold_empty!(serde_json::Value, std::path::PathBuf,);
impl<T: TomlScaffold> TomlScaffold for Vec<T> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<T: TomlScaffold> TomlScaffold for Option<T> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<K: Serialize + JsonSchema, V: TomlScaffold> TomlScaffold for std::collections::HashMap<K, V> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<K: Serialize + JsonSchema, V: TomlScaffold> TomlScaffold for std::collections::BTreeMap<K, V> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<T: TomlScaffold> TomlScaffold for std::collections::HashSet<T> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<T: TomlScaffold> TomlScaffold for std::collections::BTreeSet<T> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}
impl<T: TomlScaffold> TomlScaffold for Box<T> {
fn format_preferences() -> std::collections::HashMap<FieldPath, String> {
std::collections::HashMap::new()
}
}