From 7d894d9223ff05a2597011a898aa38760c16916f Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 25 Jul 2020 17:02:09 +0200 Subject: Suggestion: Add `apply_to` method I didn't feel like writing a test for `Suggestion.apply()`, which writes files, so decided to write a different version that used the original file and a writer. Changed the `Suggestion.suggestion()` function to not prepend "+" to suggestion lines so we can use the function to extract the suggested lines unmodified from the comment. Kept the old version around as `suggestion_patch()` because we may need it to generate patches. Copied the code from `Suggestion.apply()`, except write the changes to `writer` instead of the file at `Suggestion.path`. --- src/lib.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 5827a2c..34617d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,6 +70,7 @@ pub struct Suggestion { path: String, + // TODO: start_line can be null original_start_line: usize, original_end_line: usize, } @@ -91,17 +92,23 @@ impl Suggestion { diff[last] = diff.last().unwrap() .replacen(" ", "-", 1); - diff.push(self.suggestion()); + diff.push(self.suggestion_patch()); diff.join("\n") } - fn suggestion(&self) -> String { + fn suggestion_patch(&self) -> String { let re = Regex::new(r"(?s).*(?-s)```\s*suggestion.*\n").unwrap(); let s = re.replace(&self.comment, "+"); s.replace("```", "") } + fn suggestion(&self) -> String { + let re = Regex::new(r"(?s).*(?-s)```\s*suggestion.*\n").unwrap(); + let s = re.replace(&self.comment, ""); + s.replace("```", "") + } + fn apply(&self) -> Result<(), Error> { let repo = Repository::open(".").unwrap(); let repo_root = repo.workdir().unwrap(); @@ -136,6 +143,30 @@ impl Suggestion { Ok(()) } + + fn apply_to(&self, writer: &mut W) ->Result<(), Error> { + let repo = Repository::open(".").unwrap(); + let repo_root = repo.workdir().unwrap(); + + let original = File::open(repo_root.join(&self.path)).unwrap(); + let reader = BufReader::new(original); + + for (i, line) in reader.lines().enumerate() { + match line { + Ok(l) => { + if i < self.original_start_line + || i > self.original_end_line { + writeln!(writer, "{}", l).unwrap(); + } else if i == self.original_end_line { + write!(writer, "{}", self.suggestion()).unwrap(); + } + }, + Err(e) => panic!(e), + } + } + + Ok(()) + } } #[cfg(test)] @@ -276,4 +307,58 @@ mod tests { println!("{:?}", commit); println!("{}", std::str::from_utf8(blob).unwrap()); } + + #[test] + fn suggestion_apply_to_writes_patch_to_writer() { + use std::io::Cursor; + + use tempfile::NamedTempFile; + + + let mut temp = NamedTempFile::new().unwrap(); + let original = r#" + ‘Beware the Jabberwock, my son! + The jaws that bite, the claws that catch! + Beware the Jubjub bird, and shun + The frumious Bandersnatch!’ + + He took his vorpal blade in hand: + Long time the manxome foe he sought-- + So rested he by the Tumtum tree, + And stood awhile in thought. +"#; + + write!(temp, "{}", original).unwrap(); + + let suggestion = Suggestion { + diff: "".to_owned(), + comment: r#"``` suggestion + He took his vorpal sword in hand: + Long time the manxome foe he sought— +```"#.to_owned(), + path: temp.path().to_string_lossy().to_string(), + original_start_line: 6, + original_end_line: 7, + }; + + let expected = r#" + ‘Beware the Jabberwock, my son! + The jaws that bite, the claws that catch! + Beware the Jubjub bird, and shun + The frumious Bandersnatch!’ + + He took his vorpal sword in hand: + Long time the manxome foe he sought— + So rested he by the Tumtum tree, + And stood awhile in thought. +"#; + + let mut actual = Cursor::new(Vec::new()); + suggestion.apply_to(&mut actual).unwrap(); + + assert_eq!( + std::str::from_utf8(&actual.into_inner()).unwrap(), + expected, + ); + } } -- cgit v1.2.3