use serde::Deserialize;
const DEFAULT_INDENT_WIDTH: usize = 4;
const DEFAULT_TAB_WIDTH: usize = 4;
#[derive(Debug, Default, Clone, Deserialize)]
pub struct EditorToml {
pub indent_width: Option<usize>,
pub tab_width: Option<usize>,
pub use_tabs: Option<bool>,
pub show_whitespace: Option<bool>,
pub format_on_save: Option<bool>,
}
#[derive(Debug, Clone, Copy)]
pub struct EditorConfig {
pub indent_width: usize,
pub tab_width: usize,
pub use_tabs: bool,
pub show_whitespace: bool,
pub format_on_save: bool,
}
impl Default for EditorConfig {
fn default() -> Self {
Self {
indent_width: DEFAULT_INDENT_WIDTH,
tab_width: DEFAULT_TAB_WIDTH,
use_tabs: false,
show_whitespace: false,
format_on_save: true,
}
}
}
impl EditorConfig {
pub fn overlay(self, user: &EditorToml) -> Self {
Self {
indent_width: user.indent_width.unwrap_or(self.indent_width),
tab_width: user.tab_width.unwrap_or(self.tab_width),
use_tabs: user.use_tabs.unwrap_or(self.use_tabs),
show_whitespace: user.show_whitespace.unwrap_or(self.show_whitespace),
format_on_save: user.format_on_save.unwrap_or(self.format_on_save),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_when_user_omits_fields() {
let eff = EditorConfig::default().overlay(&EditorToml::default());
assert_eq!(eff.indent_width, 4);
assert_eq!(eff.tab_width, 4);
}
#[test]
fn overlay_replaces_only_provided_fields() {
let base = EditorConfig {
indent_width: 4,
tab_width: 4,
use_tabs: false,
show_whitespace: false,
format_on_save: true,
};
let eff = base.overlay(&EditorToml {
tab_width: Some(8),
..Default::default()
});
assert_eq!(eff.indent_width, 4);
assert_eq!(eff.tab_width, 8);
}
}