]> git.lizzy.rs Git - rust.git/blob - src/formatting/newline_style.rs
Convert to free standing functions
[rust.git] / src / formatting / newline_style.rs
1 use crate::NewlineStyle;
2
3 /// Apply this newline style to the formatted text. When the style is set
4 /// to `Auto`, the `raw_input_text` is used to detect the existing line
5 /// endings.
6 ///
7 /// If the style is set to `Auto` and `raw_input_text` contains no
8 /// newlines, the `Native` style will be used.
9 pub(crate) fn apply_newline_style(
10     newline_style: NewlineStyle,
11     formatted_text: &mut String,
12     raw_input_text: &str,
13 ) {
14     use crate::NewlineStyle::*;
15     let mut style = newline_style;
16     if style == Auto {
17         style = auto_detect_newline_style(raw_input_text);
18     }
19     if style == Native {
20         style = native();
21     }
22     match style {
23         Windows => {
24             let mut transformed = String::with_capacity(2 * formatted_text.capacity());
25             for c in formatted_text.chars() {
26                 match c {
27                     '\n' => transformed.push_str("\r\n"),
28                     '\r' => continue,
29                     c => transformed.push(c),
30                 }
31             }
32             *formatted_text = transformed;
33         }
34         Unix => return,
35         Native => unreachable!("NewlineStyle::Native"),
36         Auto => unreachable!("NewlineStyle::Auto"),
37     }
38 }
39
40 fn auto_detect_newline_style(raw_input_text: &str) -> NewlineStyle {
41     if let Some(pos) = raw_input_text.find('\n') {
42         let pos = pos.saturating_sub(1);
43         if let Some('\r') = raw_input_text.chars().nth(pos) {
44             NewlineStyle::Windows
45         } else {
46             NewlineStyle::Unix
47         }
48     } else {
49         NewlineStyle::Native
50     }
51 }
52
53 fn native() -> NewlineStyle {
54     if cfg!(windows) {
55         NewlineStyle::Windows
56     } else {
57         NewlineStyle::Unix
58     }
59 }
60
61 #[cfg(test)]
62 mod tests {
63     use super::*;
64
65     #[test]
66     fn test_newline_style_auto_detect() {
67         let lf = "One\nTwo\nThree";
68         let crlf = "One\r\nTwo\r\nThree";
69         let none = "One Two Three";
70
71         assert_eq!(NewlineStyle::Unix, auto_detect_newline_style(lf));
72         assert_eq!(NewlineStyle::Windows, auto_detect_newline_style(crlf));
73         assert_eq!(NewlineStyle::Native, auto_detect_newline_style(none));
74     }
75
76     #[test]
77     fn test_newline_style_auto_apply() {
78         let auto = NewlineStyle::Auto;
79
80         let formatted_text = "One\nTwo\nThree";
81         let raw_input_text = "One\nTwo\nThree";
82
83         let mut out = String::from(formatted_text);
84         apply_newline_style(auto, &mut out, raw_input_text);
85         assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
86
87         let formatted_text = "One\nTwo\nThree";
88         let raw_input_text = "One\r\nTwo\r\nThree";
89
90         let mut out = String::from(formatted_text);
91         apply_newline_style(auto, &mut out, raw_input_text);
92         assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
93
94         #[cfg(not(windows))]
95         {
96             let formatted_text = "One\nTwo\nThree";
97             let raw_input_text = "One Two Three";
98
99             let mut out = String::from(formatted_text);
100             apply_newline_style(auto, &mut out, raw_input_text);
101             assert_eq!(
102                 "One\nTwo\nThree", &out,
103                 "auto-native-unix should detect 'lf'"
104             );
105         }
106
107         #[cfg(windows)]
108         {
109             let formatted_text = "One\nTwo\nThree";
110             let raw_input_text = "One Two Three";
111
112             let mut out = String::from(formatted_text);
113             apply_newline_style(auto, &mut out, raw_input_text);
114             assert_eq!(
115                 "One\r\nTwo\r\nThree", &out,
116                 "auto-native-windows should detect 'crlf'"
117             );
118         }
119     }
120 }