csv-sniffer 0.3.0

A CSV file format sniffer for Rust
Documentation
use std::io::{Read, Seek, SeekFrom};

use memchr;

use error::*;

pub(crate) fn preamble_skipcount<R: Read>(reader: &mut R, n_preamble_rows: usize) -> Result<usize> {
    if n_preamble_rows == 0 {
        return Ok(0);
    }
    let mut skipcount = 0;
    loop {
        let cap = 1 << 12;
        let mut buffer = vec![0; cap];
        unsafe {
            buffer.set_len(cap);
        }
        let n_read = reader.read(&mut buffer)?;
        let mut crlf_pos = 0;
        let mut found = true;
        for _ in 0..n_preamble_rows {
            match memchr::memchr(b'\n', &buffer[crlf_pos..]) {
                Some(pos) => {
                    crlf_pos += pos + 1;
                }
                None => {
                    found = false;
                    break;
                }
            }
        }
        if found {
            skipcount += crlf_pos;
            break;
        } else {
            skipcount += cap.min(n_read);
        }
    }
    Ok(skipcount)
}

pub(crate) fn snip_preamble<R: Read + Seek>(mut reader: R, n_preamble_rows: usize) -> Result<()> {
    let seek_point = preamble_skipcount(&mut reader, n_preamble_rows)?;
    reader.seek(SeekFrom::Start(seek_point as u64))?;
    Ok(())
}