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