Repository: dathere/qsv (language: rust)

Issue:
qsv diff -s <arg> if both files use the same delimiter
I had to do a `diff` on two semicolon separated files, and had to enter `--delimiter-left <arg>` and `--delimiter-right <arg>`.

If both have the same delimiter, should one then not perhaps also have a `-d<arg>`?


Discussion / hints:
Once @janriemer fixes #2443, I can certainly add this "convenience" option as an enhancement.

Fix patch:
diff --git a/src/cmd/diff.rs b/src/cmd/diff.rs
index 4b73017f5..2691a539d 100644
--- a/src/cmd/diff.rs
+++ b/src/cmd/diff.rs
@@ -96,6 +96,9 @@ diff options:
 Common options:
     -h, --help                  Display this message
     -o, --output <file>         Write output to <file> instead of stdout.
+    -d, --delimiter <arg>       Set ALL delimiters to this character.
+                                Overrides --delimiter-right, --delimiter-left
+                                and --delimiter-output.
 "#;
 
 use std::io::{self, Write};
@@ -129,10 +132,19 @@ struct Args {
     flag_key:               Option<String>,
     flag_sort_columns:      Option<String>,
     flag_drop_equal_fields: bool,
+    flag_delimiter:         Option<Delimiter>,
 }
 
 pub fn run(argv: &[&str]) -> CliResult<()> {
-    let args: Args = util::get_args(USAGE, argv)?;
+    let mut args: Args = util::get_args(USAGE, argv)?;
+
+    if let Some(delim) = args.flag_delimiter {
+        [
+            args.flag_delimiter_left,
+            args.flag_delimiter_right,
+            args.flag_delimiter_output,
+        ] = [Some(delim); 3];
+    }
 
     let rconfig_left = Config::new(args.arg_input_left.as_ref())
         .delimiter(args.flag_delimiter_left)
@@ -345,6 +357,7 @@ impl<W: Write> CsvDiffWriter<W> {
         Ok(())
     }
 
+    #[inline]
     fn write_diff_byte_record(&mut self, diff_byte_record: &DiffByteRecord) -> csv::Result<()> {
         let add_sign: &[u8] = &b"+"[..];
         let remove_sign: &[u8] = &b"-"[..];


Test patch:
diff --git a/tests/test_diff.rs b/tests/test_diff.rs
index a182b8c6d..a1b231948 100644
--- a/tests/test_diff.rs
+++ b/tests/test_diff.rs
@@ -791,3 +791,89 @@ fn create_file_with_delim(wrk: &Workdir, file_path_new: &str, file_path: &str, d
 
     wrk.create_with_delim(file_path_new, got, delimiter);
 }
+
+#[test]
+fn diff_with_delimiter_overrides_all_delimiters() {
+    let wrk = Workdir::new("diff_with_delimiter_overrides_all_delimiters");
+
+    let left = vec![svec!["h1", "h2", "h3"], svec!["1", "foo", "bar"]];
+    wrk.create_with_delim("left.csv", left, b';');
+
+    let right = vec![svec!["h1", "h2", "h3"], svec!["1", "foo_changed", "bar"]];
+    wrk.create_with_delim("right.csv", right, b';');
+
+    let mut cmd = wrk.command("diff");
+    cmd.args([
+        "left.csv",
+        "right.csv",
+        "--delimiter",
+        ";",
+        // These should be overridden by --delimiter
+        "--delimiter-left",
+        ",",
+        "--delimiter-right",
+        "\t",
+        "--delimiter-output",
+        "|",
+    ]);
+
+    let got: String = wrk.stdout(&mut cmd);
+    let expected = "\
+diffresult;h1;h2;h3
+-;1;foo;bar
++;1;foo_changed;bar";
+    assert_eq!(got.as_str(), expected);
+}
+
+#[test]
+fn diff_with_tab_delimiter() {
+    let wrk = Workdir::new("diff_with_tab_delimiter");
+
+    let left = vec![svec!["h1", "h2", "h3"], svec!["1", "foo", "bar"]];
+    wrk.create_with_delim("left.csv", left, b'\t');
+
+    let right = vec![svec!["h1", "h2", "h3"], svec!["1", "foo_changed", "bar"]];
+    wrk.create_with_delim("right.csv", right, b'\t');
+
+    let mut cmd = wrk.command("diff");
+    cmd.args(["left.csv", "right.csv", "--delimiter", "\t"]);
+
+    let got: String = wrk.stdout(&mut cmd);
+    let expected = "\
+diffresult\th1\th2\th3
+-\t1\tfoo\tbar
++\t1\tfoo_changed\tbar";
+    assert_eq!(got.as_str(), expected);
+}
+
+#[test]
+fn diff_with_mixed_delimiters() {
+    let wrk = Workdir::new("diff_with_mixed_delimiters");
+
+    // Create left file with semicolon delimiter
+    let left = vec![svec!["h1", "h2", "h3"], svec!["1", "foo", "bar"]];
+    wrk.create_with_delim("left.csv", left, b';');
+
+    // Create right file with tab delimiter
+    let right = vec![svec!["h1", "h2", "h3"], svec!["1", "foo_changed", "bar"]];
+    wrk.create_with_delim("right.csv", right, b'\t');
+
+    let mut cmd = wrk.command("diff");
+    cmd.args([
+        "--delimiter-left",
+        ";",
+        "--delimiter-right",
+        "\t",
+        "--delimiter-output",
+        "|",
+        "left.csv",
+        "right.csv",
+    ]);
+
+    let got: String = wrk.stdout(&mut cmd);
+    let expected = "\
+diffresult|h1|h2|h3
+-|1|foo|bar
++|1|foo_changed|bar";
+    assert_eq!(got.as_str(), expected);
+}