simd-csv 0.13.0

Specialized Rust CSV readers/writers leveraging SIMD instructions.
Documentation
use std::fs::File;

use clap::Parser;

#[derive(Parser, Debug)]
struct Args {
    /// Path to target CSV file
    path: String,

    /// Whether to use SIMD acceleration
    #[arg(long)]
    simd: bool,

    /// Whether to write output as binary
    #[arg(long)]
    binary: bool,

    #[arg(long)]
    only_read: bool,
}

impl Args {
    fn delimiter(&self) -> u8 {
        if self.path.ends_with(".tsv") {
            b'\t'
        } else {
            b','
        }
    }
}

const DEFAULT_CAPACITY: usize = 1024 * (1 << 10);

fn main() -> anyhow::Result<()> {
    let args = Args::parse();
    let delimiter = args.delimiter();
    let file = File::open(&args.path)?;

    if args.simd {
        let mut reader = simd_csv::ReaderBuilder::with_capacity(DEFAULT_CAPACITY)
            .has_headers(false)
            .delimiter(delimiter)
            .from_reader(file);

        let mut record = simd_csv::ByteRecord::new();

        let mut writer = simd_csv::WriterBuilder::with_capacity(DEFAULT_CAPACITY)
            .delimiter(delimiter)
            .from_writer(std::io::stdout());

        while reader.read_byte_record(&mut record)? {
            if !args.only_read {
                writer.write_byte_record(&record)?;
            }
        }

        writer.flush()?;
    } else if args.binary {
        #[cfg(feature = "binary")]
        {
            let mut reader = simd_csv::ReaderBuilder::with_capacity(DEFAULT_CAPACITY)
                .has_headers(false)
                .delimiter(delimiter)
                .from_reader(file);

            let mut record = simd_csv::ByteRecord::new();

            let mut writer = simd_csv::binary::BinaryWriter::from_writer(std::io::stdout());

            while reader.read_byte_record(&mut record)? {
                if !args.only_read {
                    writer.write_byte_record(&record)?;
                }
            }

            writer.flush()?;
        }

        #[cfg(not(feature = "binary"))]
        {
            eprintln!("was not compiled with binary feature");
        }
    } else {
        let mut reader = csv::ReaderBuilder::new()
            .has_headers(false)
            .delimiter(delimiter)
            .from_reader(file);

        let mut record = csv::ByteRecord::new();

        let mut writer = csv::WriterBuilder::new()
            .delimiter(delimiter)
            .from_writer(std::io::stdout());

        while reader.read_byte_record(&mut record)? {
            if !args.only_read {
                writer.write_byte_record(&record)?;
            }
        }

        writer.flush()?;
    }

    Ok(())
}