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 const WINDOWS_NEWLINE: &str = "\r\n";
16 match effective_newline_style(newline_style, raw_input_text) {
17 EffectiveNewlineStyle::Windows => {
18 let mut transformed = String::with_capacity(2 * formatted_text.capacity());
19 for c in formatted_text.chars() {
21 LINE_FEED => transformed.push_str(WINDOWS_NEWLINE),
22 CARRIAGE_RETURN => continue,
23 c => transformed.push(c),
26 *formatted_text = transformed;
28 EffectiveNewlineStyle::Unix => {}
32 const LINE_FEED: char = '\n';
33 const CARRIAGE_RETURN: char = '\r';
35 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
36 enum EffectiveNewlineStyle {
41 fn effective_newline_style(
42 newline_style: NewlineStyle,
44 ) -> EffectiveNewlineStyle {
46 NewlineStyle::Auto => auto_detect_newline_style(raw_input_text),
47 NewlineStyle::Native => native_newline_style(),
48 NewlineStyle::Windows => EffectiveNewlineStyle::Windows,
49 NewlineStyle::Unix => EffectiveNewlineStyle::Unix,
53 fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
54 if let Some(pos) = raw_input_text.find(LINE_FEED) {
55 let pos = pos.saturating_sub(1);
56 if let Some(CARRIAGE_RETURN) = raw_input_text.chars().nth(pos) {
57 EffectiveNewlineStyle::Windows
59 EffectiveNewlineStyle::Unix
62 native_newline_style()
66 fn native_newline_style() -> EffectiveNewlineStyle {
68 EffectiveNewlineStyle::Windows
70 EffectiveNewlineStyle::Unix
79 fn test_newline_style_auto_detect() {
80 let lf = "One\nTwo\nThree";
81 let crlf = "One\r\nTwo\r\nThree";
82 let none = "One Two Three";
84 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(lf));
86 EffectiveNewlineStyle::Windows,
87 auto_detect_newline_style(crlf)
92 EffectiveNewlineStyle::Windows,
93 auto_detect_newline_style(none)
96 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(none));
101 fn test_newline_style_auto_apply() {
102 let auto = NewlineStyle::Auto;
104 let formatted_text = "One\nTwo\nThree";
105 let raw_input_text = "One\nTwo\nThree";
107 let mut out = String::from(formatted_text);
108 apply_newline_style(auto, &mut out, raw_input_text);
109 assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
111 let formatted_text = "One\nTwo\nThree";
112 let raw_input_text = "One\r\nTwo\r\nThree";
114 let mut out = String::from(formatted_text);
115 apply_newline_style(auto, &mut out, raw_input_text);
116 assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
120 let formatted_text = "One\nTwo\nThree";
121 let raw_input_text = "One Two Three";
123 let mut out = String::from(formatted_text);
124 apply_newline_style(auto, &mut out, raw_input_text);
126 "One\nTwo\nThree", &out,
127 "auto-native-unix should detect 'lf'"
133 let formatted_text = "One\nTwo\nThree";
134 let raw_input_text = "One Two Three";
136 let mut out = String::from(formatted_text);
137 apply_newline_style(auto, &mut out, raw_input_text);
139 "One\r\nTwo\r\nThree", &out,
140 "auto-native-windows should detect 'crlf'"