formatted_text: &mut String,
raw_input_text: &str,
) {
- match effective_newline_style(newline_style, raw_input_text) {
- EffectiveNewlineStyle::Windows => {
- *formatted_text = convert_to_windows_newlines(formatted_text);
- }
- EffectiveNewlineStyle::Unix => {}
+ *formatted_text = match effective_newline_style(newline_style, raw_input_text) {
+ EffectiveNewlineStyle::Windows => convert_to_windows_newlines(formatted_text),
+ EffectiveNewlineStyle::Unix => convert_to_unix_newlines(formatted_text),
}
}
const LINE_FEED: char = '\n';
const CARRIAGE_RETURN: char = '\r';
+const WINDOWS_NEWLINE: &str = "\r\n";
+const UNIX_NEWLINE: &str = "\n";
fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
- if let Some(pos) = raw_input_text.find(LINE_FEED) {
- let pos = pos.saturating_sub(1);
- if let Some(CARRIAGE_RETURN) = raw_input_text.chars().nth(pos) {
- EffectiveNewlineStyle::Windows
- } else {
- EffectiveNewlineStyle::Unix
+ let first_line_feed_pos = raw_input_text.chars().position(|ch| ch == LINE_FEED);
+ match first_line_feed_pos {
+ Some(first_line_feed_pos) => {
+ let char_before_line_feed_pos = first_line_feed_pos.saturating_sub(1);
+ let char_before_line_feed = raw_input_text.chars().nth(char_before_line_feed_pos);
+ match char_before_line_feed {
+ Some(CARRIAGE_RETURN) => EffectiveNewlineStyle::Windows,
+ _ => EffectiveNewlineStyle::Unix,
+ }
}
- } else {
- native_newline_style()
+ None => native_newline_style(),
}
}
fn convert_to_windows_newlines(formatted_text: &String) -> String {
let mut transformed = String::with_capacity(2 * formatted_text.capacity());
- for c in formatted_text.chars() {
- const WINDOWS_NEWLINE: &str = "\r\n";
- match c {
+ let mut chars = formatted_text.chars().peekable();
+ while let Some(current_char) = chars.next() {
+ let next_char = chars.peek();
+ match current_char {
LINE_FEED => transformed.push_str(WINDOWS_NEWLINE),
- CARRIAGE_RETURN => continue,
- c => transformed.push(c),
+ CARRIAGE_RETURN if next_char == Some(&LINE_FEED) => {}
+ current_char => transformed.push(current_char),
}
}
transformed
}
+fn convert_to_unix_newlines(formatted_text: &String) -> String {
+ formatted_text.replace(WINDOWS_NEWLINE, UNIX_NEWLINE)
+}
+
#[cfg(test)]
mod tests {
use super::*;
);
}
+ #[test]
+ fn auto_detects_windows_newlines_with_multibyte_char_on_first_line() {
+ assert_eq!(
+ EffectiveNewlineStyle::Windows,
+ auto_detect_newline_style("A 🎢 of a first line\r\nTwo\r\nThree")
+ );
+ }
+
#[test]
fn falls_back_to_native_newlines_if_no_newlines_are_found() {
let expected_newline_style = if cfg!(windows) {
}
#[test]
- fn test_newline_style_auto_apply() {
- let auto = NewlineStyle::Auto;
-
+ fn auto_detects_and_applies_unix_newlines() {
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\nTwo\nThree";
let mut out = String::from(formatted_text);
- apply_newline_style(auto, &mut out, raw_input_text);
+ apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
+ }
+ #[test]
+ fn auto_detects_and_applies_windows_newlines() {
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\r\nTwo\r\nThree";
let mut out = String::from(formatted_text);
- apply_newline_style(auto, &mut out, raw_input_text);
+ apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
+ }
- #[cfg(not(windows))]
- {
- let formatted_text = "One\nTwo\nThree";
- let raw_input_text = "One Two Three";
+ #[test]
+ fn auto_detects_and_applies_native_newlines() {
+ let formatted_text = "One\nTwo\nThree";
+ let raw_input_text = "One Two Three";
+
+ let mut out = String::from(formatted_text);
+ apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
- let mut out = String::from(formatted_text);
- apply_newline_style(auto, &mut out, raw_input_text);
+ if cfg!(windows) {
+ assert_eq!(
+ "One\r\nTwo\r\nThree", &out,
+ "auto-native-windows should detect 'crlf'"
+ );
+ } else {
assert_eq!(
"One\nTwo\nThree", &out,
"auto-native-unix should detect 'lf'"
);
}
+ }
- #[cfg(windows)]
- {
- let formatted_text = "One\nTwo\nThree";
- let raw_input_text = "One Two Three";
+ #[test]
+ fn applies_unix_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\r\nTwo\nThree",
+ "One\nTwo\nThree",
+ NewlineStyle::Unix,
+ );
+ }
- let mut out = String::from(formatted_text);
- apply_newline_style(auto, &mut out, raw_input_text);
- assert_eq!(
- "One\r\nTwo\r\nThree", &out,
- "auto-native-windows should detect 'crlf'"
- );
- }
+ #[test]
+ fn applying_unix_newlines_changes_nothing_for_unix_newlines() {
+ let formatted_text = "One\nTwo\nThree";
+ test_newlines_are_applied_correctly(formatted_text, formatted_text, NewlineStyle::Unix);
+ }
+
+ #[test]
+ fn applies_unix_newlines_to_string_with_unix_and_windows_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\r\nTwo\r\nThree\nFour",
+ "One\nTwo\nThree\nFour",
+ NewlineStyle::Unix,
+ );
+ }
+
+ #[test]
+ fn applies_windows_newlines_to_string_with_unix_and_windows_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\nTwo\nThree\r\nFour",
+ "One\r\nTwo\r\nThree\r\nFour",
+ NewlineStyle::Windows,
+ );
+ }
+
+ #[test]
+ fn applying_windows_newlines_changes_nothing_for_windows_newlines() {
+ let formatted_text = "One\r\nTwo\r\nThree";
+ test_newlines_are_applied_correctly(formatted_text, formatted_text, NewlineStyle::Windows);
+ }
+
+ #[test]
+ fn keeps_carriage_returns_when_applying_windows_newlines_to_str_with_unix_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\nTwo\nThree\rDrei",
+ "One\r\nTwo\r\nThree\rDrei",
+ NewlineStyle::Windows,
+ );
+ }
+
+ #[test]
+ fn keeps_carriage_returns_when_applying_unix_newlines_to_str_with_unix_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\nTwo\nThree\rDrei",
+ "One\nTwo\nThree\rDrei",
+ NewlineStyle::Unix,
+ );
+ }
+
+ #[test]
+ fn keeps_carriage_returns_when_applying_windows_newlines_to_str_with_windows_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\r\nTwo\r\nThree\rDrei",
+ "One\r\nTwo\r\nThree\rDrei",
+ NewlineStyle::Windows,
+ );
+ }
+
+ #[test]
+ fn keeps_carriage_returns_when_applying_unix_newlines_to_str_with_windows_newlines() {
+ test_newlines_are_applied_correctly(
+ "One\r\nTwo\r\nThree\rDrei",
+ "One\nTwo\nThree\rDrei",
+ NewlineStyle::Unix,
+ );
+ }
+
+ fn test_newlines_are_applied_correctly(
+ input: &str,
+ expected: &str,
+ newline_style: NewlineStyle,
+ ) {
+ let mut out = String::from(input);
+ apply_newline_style(newline_style, &mut out, input);
+ assert_eq!(expected, &out);
}
}