Extract applying of newline style into own mod

This commit is contained in:
Ruben Schmidmeister 2019-04-24 19:40:21 +02:00
parent 5274b49caa
commit ba5b2e9c9b
No known key found for this signature in database
GPG Key ID: 29387B5A7AAF863F
3 changed files with 120 additions and 112 deletions

View File

@ -132,62 +132,6 @@ configuration_option_enum! { NewlineStyle:
Native, // \r\n in Windows, \n on other platforms
}
impl NewlineStyle {
fn auto_detect(raw_input_text: &str) -> NewlineStyle {
if let Some(pos) = raw_input_text.find('\n') {
let pos = pos.saturating_sub(1);
if let Some('\r') = raw_input_text.chars().nth(pos) {
NewlineStyle::Windows
} else {
NewlineStyle::Unix
}
} else {
NewlineStyle::Native
}
}
fn native() -> NewlineStyle {
if cfg!(windows) {
NewlineStyle::Windows
} else {
NewlineStyle::Unix
}
}
/// Apply this newline style to the formatted text. When the style is set
/// to `Auto`, the `raw_input_text` is used to detect the existing line
/// endings.
///
/// If the style is set to `Auto` and `raw_input_text` contains no
/// newlines, the `Native` style will be used.
pub(crate) fn apply(self, formatted_text: &mut String, raw_input_text: &str) {
use crate::NewlineStyle::*;
let mut style = self;
if style == Auto {
style = Self::auto_detect(raw_input_text);
}
if style == Native {
style = Self::native();
}
match style {
Windows => {
let mut transformed = String::with_capacity(2 * formatted_text.capacity());
for c in formatted_text.chars() {
match c {
'\n' => transformed.push_str("\r\n"),
'\r' => continue,
c => transformed.push(c),
}
}
*formatted_text = transformed;
}
Unix => return,
Native => unreachable!("NewlineStyle::Native"),
Auto => unreachable!("NewlineStyle::Auto"),
}
}
}
configuration_option_enum! { BraceStyle:
AlwaysNextLine,
PreferSameLine,
@ -493,59 +437,3 @@ impl Edition {
}
}
}
#[test]
fn test_newline_style_auto_detect() {
let lf = "One\nTwo\nThree";
let crlf = "One\r\nTwo\r\nThree";
let none = "One Two Three";
assert_eq!(NewlineStyle::Unix, NewlineStyle::auto_detect(lf));
assert_eq!(NewlineStyle::Windows, NewlineStyle::auto_detect(crlf));
assert_eq!(NewlineStyle::Native, NewlineStyle::auto_detect(none));
}
#[test]
fn test_newline_style_auto_apply() {
let auto = NewlineStyle::Auto;
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\nTwo\nThree";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\r\nTwo\r\nThree";
let mut out = String::from(formatted_text);
auto.apply(&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";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
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";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
assert_eq!(
"One\r\nTwo\r\nThree", &out,
"auto-native-windows should detect 'crlf'"
);
}
}

View File

@ -20,6 +20,8 @@ use crate::utils::{count_newlines, get_skip_macro_names};
use crate::visitor::{FmtVisitor, SnippetProvider};
use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session};
mod newline_style;
// A map of the files of a crate, with their new content
pub(crate) type SourceFile = Vec<FileRecord>;
pub(crate) type FileRecord = (FileName, String);

View File

@ -0,0 +1,118 @@
use crate::NewlineStyle;
impl NewlineStyle {
fn auto_detect(raw_input_text: &str) -> NewlineStyle {
if let Some(pos) = raw_input_text.find('\n') {
let pos = pos.saturating_sub(1);
if let Some('\r') = raw_input_text.chars().nth(pos) {
NewlineStyle::Windows
} else {
NewlineStyle::Unix
}
} else {
NewlineStyle::Native
}
}
fn native() -> NewlineStyle {
if cfg!(windows) {
NewlineStyle::Windows
} else {
NewlineStyle::Unix
}
}
/// Apply this newline style to the formatted text. When the style is set
/// to `Auto`, the `raw_input_text` is used to detect the existing line
/// endings.
///
/// If the style is set to `Auto` and `raw_input_text` contains no
/// newlines, the `Native` style will be used.
pub(crate) fn apply(self, formatted_text: &mut String, raw_input_text: &str) {
use crate::NewlineStyle::*;
let mut style = self;
if style == Auto {
style = Self::auto_detect(raw_input_text);
}
if style == Native {
style = Self::native();
}
match style {
Windows => {
let mut transformed = String::with_capacity(2 * formatted_text.capacity());
for c in formatted_text.chars() {
match c {
'\n' => transformed.push_str("\r\n"),
'\r' => continue,
c => transformed.push(c),
}
}
*formatted_text = transformed;
}
Unix => return,
Native => unreachable!("NewlineStyle::Native"),
Auto => unreachable!("NewlineStyle::Auto"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_newline_style_auto_detect() {
let lf = "One\nTwo\nThree";
let crlf = "One\r\nTwo\r\nThree";
let none = "One Two Three";
assert_eq!(NewlineStyle::Unix, NewlineStyle::auto_detect(lf));
assert_eq!(NewlineStyle::Windows, NewlineStyle::auto_detect(crlf));
assert_eq!(NewlineStyle::Native, NewlineStyle::auto_detect(none));
}
#[test]
fn test_newline_style_auto_apply() {
let auto = NewlineStyle::Auto;
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\nTwo\nThree";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
let formatted_text = "One\nTwo\nThree";
let raw_input_text = "One\r\nTwo\r\nThree";
let mut out = String::from(formatted_text);
auto.apply(&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";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
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";
let mut out = String::from(formatted_text);
auto.apply(&mut out, raw_input_text);
assert_eq!(
"One\r\nTwo\r\nThree", &out,
"auto-native-windows should detect 'crlf'"
);
}
}
}