aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2020-07-26 03:28:18 +0200
committerTeddy Wing2020-07-26 03:35:42 +0200
commit985b115cc519c67575d98d1b89b9a293ada67fbb (patch)
tree4540de0a47e316ef2a51767c9eae8c59809a9edd
parent31589ef27a2942ea94f7d20e228d136cee1e654b (diff)
downloadgit-suggestion-985b115cc519c67575d98d1b89b9a293ada67fbb.tar.bz2
Suggestion.apply_to(): Use line endings consistent with file
Make the suggestion's line endings consistent with those used in the file. By default, the suggestion block we get from the GitHub API uses CRLF line endings. These need to be converted to be consistent with the file the change is being applied to.
-rw-r--r--src/lib.rs38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index a510b9f..3074dda 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -66,6 +66,12 @@ impl<'a> Client<'a> {
}
}
+#[derive(Debug, PartialEq)]
+enum LineEnding {
+ Lf,
+ CrLf,
+}
+
#[derive(Debug, Deserialize)]
pub struct Suggestion {
#[serde(rename = "diff_hunk")]
@@ -111,9 +117,20 @@ impl Suggestion {
}
fn suggestion(&self) -> String {
+ self.suggestion_with_line_ending(&LineEnding::Lf)
+ }
+
+ fn suggestion_with_line_ending(&self, line_ending: &LineEnding) -> String {
let re = Regex::new(r"(?s).*(?-s)```\s*suggestion.*\n").unwrap();
let s = re.replace(&self.comment, "");
- s.replace("```", "")
+ let s = s.replace("```", "");
+
+ // Suggestion blocks use CRLF by default.
+ if *line_ending == LineEnding::Lf {
+ return s.replace('\r', "");
+ }
+
+ s
}
pub fn apply(&self) -> Result<(), Error> {
@@ -143,14 +160,31 @@ impl Suggestion {
) -> Result<(), Error> {
let original = File::open(from).unwrap();
let reader = BufReader::new(original);
+ let mut line_ending = LineEnding::Lf;
for (i, line) in reader.lines().enumerate() {
let line_number = i + 1;
match line {
Ok(l) => {
+ // Determine which line endings the file uses by looking at
+ // the first line. If the second-to-last character on the
+ // first line is "\r", assume CRLF. Otherwise, default to
+ // LF.
+ if line_number == 1 {
+ if let Some(c) = l.chars().rev().nth(2) {
+ if c == '\r' {
+ line_ending = LineEnding::CrLf;
+ }
+ }
+ }
+
if line_number == self.original_end_line {
- write!(writer, "{}", self.suggestion()).unwrap();
+ write!(
+ writer,
+ "{}",
+ self.suggestion_with_line_ending(&line_ending),
+ ).unwrap();
} else if self.original_start_line.is_none()
|| line_number < self.original_start_line.unwrap()
|| line_number > self.original_end_line {