1 use crate::NewlineStyle;
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
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,
14 match effective_newline_style(newline_style, raw_input_text) {
15 EffectiveNewlineStyle::Windows => {
16 *formatted_text = convert_to_windows_newlines(formatted_text);
18 EffectiveNewlineStyle::Unix => {}
22 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
23 enum EffectiveNewlineStyle {
28 fn effective_newline_style(
29 newline_style: NewlineStyle,
31 ) -> EffectiveNewlineStyle {
33 NewlineStyle::Auto => auto_detect_newline_style(raw_input_text),
34 NewlineStyle::Native => native_newline_style(),
35 NewlineStyle::Windows => EffectiveNewlineStyle::Windows,
36 NewlineStyle::Unix => EffectiveNewlineStyle::Unix,
40 const LINE_FEED: char = '\n';
41 const CARRIAGE_RETURN: char = '\r';
43 fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
44 if let Some(pos) = raw_input_text.find(LINE_FEED) {
45 let pos = pos.saturating_sub(1);
46 if let Some(CARRIAGE_RETURN) = raw_input_text.chars().nth(pos) {
47 EffectiveNewlineStyle::Windows
49 EffectiveNewlineStyle::Unix
52 native_newline_style()
56 fn native_newline_style() -> EffectiveNewlineStyle {
58 EffectiveNewlineStyle::Windows
60 EffectiveNewlineStyle::Unix
64 fn convert_to_windows_newlines(formatted_text: &String) -> String {
65 let mut transformed = String::with_capacity(2 * formatted_text.capacity());
66 for c in formatted_text.chars() {
67 const WINDOWS_NEWLINE: &str = "\r\n";
69 LINE_FEED => transformed.push_str(WINDOWS_NEWLINE),
70 CARRIAGE_RETURN => continue,
71 c => transformed.push(c),
82 fn test_newline_style_auto_detect() {
83 let lf = "One\nTwo\nThree";
84 let crlf = "One\r\nTwo\r\nThree";
85 let none = "One Two Three";
87 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(lf));
89 EffectiveNewlineStyle::Windows,
90 auto_detect_newline_style(crlf)
95 EffectiveNewlineStyle::Windows,
96 auto_detect_newline_style(none)
99 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(none));
104 fn test_newline_style_auto_apply() {
105 let auto = NewlineStyle::Auto;
107 let formatted_text = "One\nTwo\nThree";
108 let raw_input_text = "One\nTwo\nThree";
110 let mut out = String::from(formatted_text);
111 apply_newline_style(auto, &mut out, raw_input_text);
112 assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
114 let formatted_text = "One\nTwo\nThree";
115 let raw_input_text = "One\r\nTwo\r\nThree";
117 let mut out = String::from(formatted_text);
118 apply_newline_style(auto, &mut out, raw_input_text);
119 assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
123 let formatted_text = "One\nTwo\nThree";
124 let raw_input_text = "One Two Three";
126 let mut out = String::from(formatted_text);
127 apply_newline_style(auto, &mut out, raw_input_text);
129 "One\nTwo\nThree", &out,
130 "auto-native-unix should detect 'lf'"
136 let formatted_text = "One\nTwo\nThree";
137 let raw_input_text = "One Two Three";
139 let mut out = String::from(formatted_text);
140 apply_newline_style(auto, &mut out, raw_input_text);
142 "One\r\nTwo\r\nThree", &out,
143 "auto-native-windows should detect 'crlf'"