# HG changeset patch
# User Simon Sapin <simon.sapin@octobus.net>
# Date 1636112215 -3600
#      Fri Nov 05 12:36:55 2021 +0100
# Node ID c6e49a0f875944701a061acb4a909f447e1293df
# Parent  0a2c98d9becb92af2a4339e5dc5ca8302e6a80bf
Extract subprocess handling into a new function

diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -53,17 +53,15 @@
             .to_str()
             .ok_or("Non-Unicode base name")?;
         let today = time::OffsetDateTime::now_utc().date();
-        let hg_id_output = process::Command::new("hg")
-            .arg("id")
-            .arg("--id")
-            .arg("-R")
-            .arg(&self.directory)
-            .output()?;
-        let id = if hg_id_output.status.success() {
-            format!("_{}", str::from_utf8(&hg_id_output.stdout)?.trim())
+        let id = if let Some(stdout) = subprocess_output(
+            process::Command::new("hg")
+                .arg("id")
+                .arg("--id")
+                .arg("-R")
+                .arg(&self.directory),
+        )? {
+            format!("_{}", stdout)
         } else {
-            let hg_stderr = str::from_utf8(&hg_id_output.stderr)?;
-            eprintln!("{}", style(hg_stderr.trim()).red());
             println!("Not a Mercurial repository?");
             format!("")
         };
@@ -167,6 +165,19 @@
     }
 }
 
+/// If the proccess has a successful exit code, return its trimmed stdout
+/// If the process has an error exit code, print its stderr in red and return None
+/// Return an error if the spawning the process or UTF-8 decoding fails
+fn subprocess_output(command: &mut process::Command) -> Result<Option<String>> {
+    let out = command.output()?;
+    if out.status.success() {
+        Ok(Some(str::from_utf8(&out.stdout)?.trim().to_owned()))
+    } else {
+        eprintln!("{}", style(str::from_utf8(&out.stderr)?.trim()).red());
+        Ok(None)
+    }
+}
+
 struct Tee<A, B>(A, B);
 
 impl<A: io::Write, B: io::Write> io::Write for Tee<A, B> {