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 let mut transformed = String::with_capacity(2 * formatted_text.capacity());
17 for c in formatted_text.chars() {
19 '\n' => transformed.push_str("\r\n"),
21 c => transformed.push(c),
24 *formatted_text = transformed;
26 EffectiveNewlineStyle::Unix => {}
30 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
31 enum EffectiveNewlineStyle {
36 fn effective_newline_style(
37 newline_style: NewlineStyle,
39 ) -> EffectiveNewlineStyle {
41 NewlineStyle::Auto => auto_detect_newline_style(raw_input_text),
42 NewlineStyle::Native => native_newline_style(),
43 NewlineStyle::Windows => EffectiveNewlineStyle::Windows,
44 NewlineStyle::Unix => EffectiveNewlineStyle::Unix,
48 fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
49 if let Some(pos) = raw_input_text.find('\n') {
50 let pos = pos.saturating_sub(1);
51 if let Some('\r') = raw_input_text.chars().nth(pos) {
52 EffectiveNewlineStyle::Windows
54 EffectiveNewlineStyle::Unix
57 native_newline_style()
61 fn native_newline_style() -> EffectiveNewlineStyle {
63 EffectiveNewlineStyle::Windows
65 EffectiveNewlineStyle::Unix
74 fn test_newline_style_auto_detect() {
75 let lf = "One\nTwo\nThree";
76 let crlf = "One\r\nTwo\r\nThree";
77 let none = "One Two Three";
79 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(lf));
81 EffectiveNewlineStyle::Windows,
82 auto_detect_newline_style(crlf)
87 EffectiveNewlineStyle::Windows,
88 auto_detect_newline_style(none)
91 assert_eq!(EffectiveNewlineStyle::Unix, auto_detect_newline_style(none));
96 fn test_newline_style_auto_apply() {
97 let auto = NewlineStyle::Auto;
99 let formatted_text = "One\nTwo\nThree";
100 let raw_input_text = "One\nTwo\nThree";
102 let mut out = String::from(formatted_text);
103 apply_newline_style(auto, &mut out, raw_input_text);
104 assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
106 let formatted_text = "One\nTwo\nThree";
107 let raw_input_text = "One\r\nTwo\r\nThree";
109 let mut out = String::from(formatted_text);
110 apply_newline_style(auto, &mut out, raw_input_text);
111 assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
115 let formatted_text = "One\nTwo\nThree";
116 let raw_input_text = "One Two Three";
118 let mut out = String::from(formatted_text);
119 apply_newline_style(auto, &mut out, raw_input_text);
121 "One\nTwo\nThree", &out,
122 "auto-native-unix should detect 'lf'"
128 let formatted_text = "One\nTwo\nThree";
129 let raw_input_text = "One Two Three";
131 let mut out = String::from(formatted_text);
132 apply_newline_style(auto, &mut out, raw_input_text);
134 "One\r\nTwo\r\nThree", &out,
135 "auto-native-windows should detect 'crlf'"