Skip to main content

easydoc_writer/style/
auto_width.rs

1//! 自动列宽策略。
2//!
3//! 对应 Java: `com.alibaba.excel.write.metadata.style.WriteCellStyle#autoSizeColumnStrategy`
4
5/// 自动列宽计算策略。
6///
7/// 根据每列中最长的单元格内容计算列宽。
8#[derive(Debug, Clone, Default)]
9pub struct AutoWidthStrategy {
10    /// Minimum column width in twips (default: ~1 character).
11    pub min_width: u32,
12    /// Maximum column width in twips (default: ~40 characters).
13    pub max_width: u32,
14}
15
16impl AutoWidthStrategy {
17    /// Creates a new auto-width strategy with defaults.
18    #[must_use]
19    pub fn new() -> Self {
20        Self {
21            min_width: 240,  // ~1 character at 11pt
22            max_width: 9600, // ~40 characters at 11pt
23        }
24    }
25
26    /// Calculates the width for a column based on its content.
27    #[must_use]
28    pub fn calculate_width(&self, max_content_length: usize) -> u32 {
29        let char_width = 240u32; // approximate twips per character at 11pt
30        // 防止 usize→u32 截断溢出:先 clamp 长度再乘
31        let clamped_len = u32::try_from(max_content_length).unwrap_or(u32::MAX);
32        let width = clamped_len.saturating_mul(char_width);
33        width.clamp(self.min_width, self.max_width)
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn default_strategy() {
43        let s = AutoWidthStrategy::default();
44        assert_eq!(s.min_width, 0);
45        assert_eq!(s.max_width, 0);
46    }
47
48    #[test]
49    fn new_has_correct_defaults() {
50        let s = AutoWidthStrategy::new();
51        assert_eq!(s.min_width, 240);
52        assert_eq!(s.max_width, 9600);
53    }
54
55    #[test]
56    fn calculate_width_short_content() {
57        let s = AutoWidthStrategy::new();
58        let w = s.calculate_width(1);
59        assert_eq!(w, 240); // clamped to min
60    }
61
62    #[test]
63    fn calculate_width_medium_content() {
64        let s = AutoWidthStrategy::new();
65        let w = s.calculate_width(10);
66        assert_eq!(w, 2400); // 10 * 240
67    }
68
69    #[test]
70    fn calculate_width_long_content() {
71        let s = AutoWidthStrategy::new();
72        let w = s.calculate_width(100);
73        assert_eq!(w, 9600); // clamped to max
74    }
75
76    #[test]
77    fn calculate_width_zero_content() {
78        let s = AutoWidthStrategy::new();
79        let w = s.calculate_width(0);
80        assert_eq!(w, 240); // clamped to min
81    }
82
83    #[test]
84    fn custom_min_max() {
85        let s = AutoWidthStrategy {
86            min_width: 100,
87            max_width: 5000,
88        };
89        assert_eq!(s.calculate_width(0), 100);
90        assert_eq!(s.calculate_width(100), 5000);
91    }
92}