Repository: dathere/qsv (language: rust)

Issue:
Error when using `qsv reverse` when index file is present
**Describe the bug**
At times when I'm using `qsv reverse` and an index file is present for a given CSV file, I get an io error even though the reversed output is also produced as intended.

**To Reproduce**
Steps to reproduce the behavior:
1. Generate an index file for a CSV file with `qsv index`.
2. Run `qsv reverse <filepath>`.

**Expected behavior**
No error when reversing the file even with the index file present.

**Screenshots/Backtrace/Sample Data**
![image](https://github.com/user-attachments/assets/b28e58fd-fa2a-4e4e-9067-9f64d26a3911)

**Desktop (please complete the following information):**
 - OS: Ubuntu
 - qsv Version: 0.129.1



Discussion / hints:
Good catch @rzmk!

Fix patch:
diff --git a/src/cmd/reverse.rs b/src/cmd/reverse.rs
index a1aa9b0c6..99bbc75dd 100644
--- a/src/cmd/reverse.rs
+++ b/src/cmd/reverse.rs
@@ -56,10 +56,12 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
         let mut record = csv::ByteRecord::new();
         let mut pos = idx_file.count().saturating_sub(1);
         idx_file.seek(pos)?;
-        while idx_file.read_byte_record(&mut record)? {
+        let mut more_data = true;
+        while more_data {
+            idx_file.read_byte_record(&mut record)?;
             wtr.write_byte_record(&record)?;
             pos -= 1;
-            idx_file.seek(pos)?; // seek to next pos
+            more_data = idx_file.seek(pos).is_ok();
         }
     } else {
         // we don't have an index, we need to read the entire file into memory


Test patch:
diff --git a/tests/test_reverse.rs b/tests/test_reverse.rs
index 855905845..853a3b103 100644
--- a/tests/test_reverse.rs
+++ b/tests/test_reverse.rs
@@ -44,7 +44,6 @@ fn prop_reverse_no_headers() {
     qcheck(p as fn(CsvData) -> bool);
 }
 
-#[cfg(not(target_os = "macos"))]
 fn prop_reverse_indexed(name: &str, rows: CsvData, headers: bool) -> bool {
     let wrk = Workdir::new(name);
     wrk.create_indexed("in.csv", rows.clone());
@@ -69,10 +68,7 @@ fn prop_reverse_indexed(name: &str, rows: CsvData, headers: bool) -> bool {
     rassert_eq!(got, expected)
 }
 
-// skip on macOS for now because this fails on GH action runner
-// but runs successfully on macOS locally
 #[test]
-#[cfg(not(target_os = "macos"))]
 fn prop_reverse_headers_indexed() {
     fn p(rows: CsvData) -> bool {
         prop_reverse_indexed("prop_reverse_headers_indexed", rows, true)
@@ -80,9 +76,7 @@ fn prop_reverse_headers_indexed() {
     qcheck(p as fn(CsvData) -> bool);
 }
 
-// same as above
 #[test]
-#[cfg(not(target_os = "macos"))]
 fn prop_reverse_no_headers_indexed() {
     fn p(rows: CsvData) -> bool {
         prop_reverse_indexed("prop_reverse_no_headers_indexed", rows, false)