sea_core/formatter/
config.rs

1//! Formatter configuration options.
2
3use serde::{Deserialize, Serialize};
4
5/// Style of indentation to use.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
7pub enum IndentStyle {
8    /// Use spaces for indentation (default).
9    #[default]
10    Spaces,
11    /// Use tabs for indentation.
12    Tabs,
13}
14
15/// Configuration options for the SEA code formatter.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct FormatConfig {
18    /// Style of indentation (spaces or tabs).
19    pub indent_style: IndentStyle,
20    /// Number of spaces per indentation level (ignored if using tabs).
21    pub indent_width: usize,
22    /// Maximum line width before wrapping (advisory).
23    pub max_line_width: usize,
24    /// Whether to ensure file ends with a newline.
25    pub trailing_newline: bool,
26    /// Whether to preserve comments in output.
27    pub preserve_comments: bool,
28    /// Whether to sort imports alphabetically.
29    pub sort_imports: bool,
30}
31
32impl Default for FormatConfig {
33    fn default() -> Self {
34        Self {
35            indent_style: IndentStyle::Spaces,
36            indent_width: 4,
37            max_line_width: 100,
38            trailing_newline: true,
39            preserve_comments: true,
40            sort_imports: true,
41        }
42    }
43}
44
45impl FormatConfig {
46    /// Create a new config with default values.
47    pub fn new() -> Self {
48        Self::default()
49    }
50
51    /// Set the indent style.
52    pub fn with_indent_style(mut self, style: IndentStyle) -> Self {
53        self.indent_style = style;
54        self
55    }
56
57    /// Set the indent width (for spaces).
58    pub fn with_indent_width(mut self, width: usize) -> Self {
59        self.indent_width = width;
60        self
61    }
62
63    /// Set whether to use tabs.
64    pub fn with_tabs(mut self) -> Self {
65        self.indent_style = IndentStyle::Tabs;
66        self
67    }
68
69    /// Get the string to use for one level of indentation.
70    pub fn indent_string(&self) -> String {
71        match self.indent_style {
72            IndentStyle::Spaces => " ".repeat(self.indent_width),
73            IndentStyle::Tabs => "\t".to_string(),
74        }
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_default_config() {
84        let config = FormatConfig::default();
85        assert_eq!(config.indent_style, IndentStyle::Spaces);
86        assert_eq!(config.indent_width, 4);
87        assert_eq!(config.max_line_width, 100);
88        assert!(config.trailing_newline);
89        assert!(config.preserve_comments);
90        assert!(config.sort_imports);
91    }
92
93    #[test]
94    fn test_indent_string_spaces() {
95        let config = FormatConfig::default().with_indent_width(2);
96        assert_eq!(config.indent_string(), "  ");
97    }
98
99    #[test]
100    fn test_indent_string_tabs() {
101        let config = FormatConfig::default().with_tabs();
102        assert_eq!(config.indent_string(), "\t");
103    }
104
105    #[test]
106    fn test_builder_pattern() {
107        let config = FormatConfig::new()
108            .with_indent_style(IndentStyle::Tabs)
109            .with_indent_width(8);
110
111        assert_eq!(config.indent_style, IndentStyle::Tabs);
112        assert_eq!(config.indent_width, 8);
113    }
114}