1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
4#[serde(rename_all = "snake_case")]
5pub enum NewlineStyle {
6 #[default]
7 Auto,
8 Native,
9 Unix,
10 Windows,
11}
12
13impl NewlineStyle {
14 pub fn newline_str(&self, input: &str) -> &'static str {
15 match self {
16 NewlineStyle::Auto => auto_detect_newline_style(input),
17 NewlineStyle::Native => native_newline_str(),
18 NewlineStyle::Unix => "\n",
19 NewlineStyle::Windows => "\r\n",
20 }
21 }
22}
23
24fn auto_detect_newline_style(input: &str) -> &'static str {
25 let first_lf = input.find('\n');
26 match first_lf {
27 Some(pos) if pos > 0 && input.as_bytes()[pos - 1] == b'\r' => "\r\n",
28 Some(_) => "\n",
29 None => native_newline_str(),
30 }
31}
32
33fn native_newline_str() -> &'static str {
34 if cfg!(target_os = "windows") {
35 "\r\n"
36 } else {
37 "\n"
38 }
39}
40
41#[derive(Clone, Debug, Serialize, Deserialize)]
42#[serde(deny_unknown_fields)]
43pub struct Format {
44 #[serde(default = "default_indent_width")]
45 pub indent_width: usize,
46
47 #[serde(default = "default_max_width")]
48 pub max_width: usize,
49
50 #[serde(default = "default_vertical_align")]
51 pub vertical_align: bool,
52
53 #[serde(default)]
54 pub newline_style: NewlineStyle,
55}
56
57impl Default for Format {
58 fn default() -> Self {
59 toml::from_str("").unwrap()
60 }
61}
62
63fn default_indent_width() -> usize {
64 4
65}
66
67fn default_max_width() -> usize {
68 120
69}
70
71fn default_vertical_align() -> bool {
72 true
73}