Skip to content

Commit 59216ba

Browse files
committed
lazycsv: Handle CSVs without trailing newline gracefully
1 parent 40ea13e commit 59216ba

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

crates/lazycsv/src/lib.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,13 @@ impl<'a> Iterator for Csv<'a> {
327327
let Some(index_relative) = memchr3(self.separator, b'\n', b'"', &self.buf[cursor..])
328328
else {
329329
self.state = IterState::Done;
330-
return None;
330+
return if start < self.buf.len() {
331+
Some(CsvIterItem::Cell(Cell {
332+
buf: &self.buf[start..],
333+
}))
334+
} else {
335+
None
336+
};
331337
};
332338
let index = index_relative + cursor;
333339

@@ -419,13 +425,16 @@ impl<'a, const COLS: usize> Iterator for CsvRowIter<'a, COLS> {
419425
}
420426
}
421427

422-
if !matches!(self.csv.next(), Some(CsvIterItem::LineEnd)) {
423-
return Some(Err(RowIterError::ColumnCountLargerThanExpected {
428+
// After reading COLS cells, the next item must be a line ending or EOF.
429+
// EOF in this context is treated as a valid input to gracefully handle
430+
// files without a trailing newline.
431+
if let None | Some(CsvIterItem::LineEnd) = self.csv.next() {
432+
Some(Ok(arr.map(|mem| unsafe { mem.assume_init() })))
433+
} else {
434+
Some(Err(RowIterError::ColumnCountLargerThanExpected {
424435
expected: COLS,
425-
}));
436+
}))
426437
}
427-
428-
Some(Ok(arr.map(|mem| unsafe { mem.assume_init() })))
429438
}
430439
}
431440

0 commit comments

Comments
 (0)