use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Clone, Default, PartialEq)]
pub enum NumberFormat {
#[default]
Unknown,
Decimal,
Hex,
Octal,
Binary,
Custom(String),
}
impl From<String> for NumberFormat {
fn from(s: String) -> Self {
Self::Custom(s)
}
}
impl fmt::Display for NumberFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NumberFormat::Hex => write!(f, "X"),
NumberFormat::Octal => write!(f, "o"),
NumberFormat::Binary => write!(f, "b"),
NumberFormat::Custom(fmt) => {
if !fmt.starts_with("#") {
write!(f, "{}", fmt)
} else {
write!(f, "{}", &fmt[1..])
}
}
_ => Ok(()),
}
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub enum FloatFormat {
#[default]
Default,
Fixed(Option<usize>),
Scientific,
General(Option<usize>),
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ParamFormatSelector {
Position(usize),
Name(String),
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct FormatterOptions {
pub indent: usize,
pub use_tabs: bool,
pub newline_before: bool,
pub newline_after: bool,
pub compact: bool,
pub force_quotes_for_vars: bool,
pub number_format: NumberFormat,
pub float_format: FloatFormat,
pub newline_before_param: bool,
pub newline_after_param: bool,
pub should_override: bool,
}
#[derive(Debug, Clone)]
pub struct WriterConfig {
pub global_options: FormatterOptions,
pub command_options: HashMap<String, FormatterOptions>,
pub command_threshold: usize,
}
impl Default for WriterConfig {
fn default() -> Self {
Self {
global_options: FormatterOptions {
indent: 4,
number_format: NumberFormat::Decimal,
..Default::default()
},
command_options: HashMap::new(),
command_threshold: 1,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_param_format_selector() {
let pos_selector = ParamFormatSelector::Position(0);
let name_selector = ParamFormatSelector::Name("test".to_string());
assert_ne!(pos_selector, name_selector);
let pos_selector2 = ParamFormatSelector::Position(0);
assert_eq!(pos_selector, pos_selector2);
let name_selector2 = ParamFormatSelector::Name("test".to_string());
assert_eq!(name_selector, name_selector2);
}
#[test]
fn test_writer_config_default() {
let default = WriterConfig::default();
assert_eq!(default.global_options.indent, 4);
assert_eq!(default.global_options.compact, false);
assert!(default.command_options.is_empty());
assert_eq!(default.command_threshold, 1);
}
#[test]
fn test_writer_config_with_custom_command_options() {
let mut command_options = HashMap::new();
let custom_options = FormatterOptions {
compact: true,
newline_after: true,
..Default::default()
};
command_options.insert("custom_command".to_string(), custom_options.clone());
let config = WriterConfig {
command_options,
..Default::default()
};
assert_eq!(config.command_options.len(), 1);
assert_eq!(
config.command_options.get("custom_command"),
Some(&custom_options)
);
}
#[test]
fn test_writer_config_with_custom_threshold() {
let config = WriterConfig {
command_threshold: 2,
..Default::default()
};
assert_eq!(config.command_threshold, 2);
}
}