Skip to content

Instantly share code, notes, and snippets.

@cristicbz
Last active October 26, 2017 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cristicbz/716ae2db680054f083edd0b271bac0cb to your computer and use it in GitHub Desktop.
Save cristicbz/716ae2db680054f083edd0b271bac0cb to your computer and use it in GitHub Desktop.
csv.rs for expressive rust
use std::env;
use std::io::{self, BufReader, BufWriter, BufRead, Write};
use std::fs::File;
use std::process;
enum Error {
Io(io::Error),
Program(&'static str),
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::Io(e)
}
}
impl From<&'static str> for Error {
fn from(e: &'static str) -> Error {
Error::Program(e)
}
}
fn main() {
let mut args = env::args();
let program = args.next().expect("cannot get program name");
let result = match (args.next(), args.next(), args.next(), args.next()) {
(Some(input), Some(column_name), Some(replacement), Some(output)) => {
replace_column_in_csv(&input, &output, &column_name, &replacement)
}
_ => Err(Error::Program("invalid arguments")),
};
match result {
Ok(()) => process::exit(0),
Err(Error::Io(io_error)) => eprintln!("{}: I/O Error: {}", program, io_error),
Err(Error::Program(error)) => eprintln!("{}: {}", program, error),
}
process::exit(1);
}
fn replace_column_in_csv(
input_filename: &str,
output_filename: &str,
replaced_column_name: &str,
replacement_value: &str,
) -> Result<(), Error> {
let mut input_lines = BufReader::new(File::open(input_filename)?).lines();
let mut output_file = BufWriter::new(File::create(output_filename)?);
let column_names = input_lines.next().ok_or("input file is empty")??;
let replaced_column_index = column_names
.split(',')
.position(|name| name == replaced_column_name)
.ok_or("column name doesn’t exist in the input file")?;
output_file.write_all(column_names.as_bytes())?;
output_file.write_all(b"\n")?;
for line in input_lines {
let line = line?;
let mut row = line.split(',').enumerate().map(|(column_index, value)| {
if column_index == replaced_column_index {
replacement_value
} else {
value
}
});
output_file.write_all(
row.next().ok_or("empty row")?.as_bytes(),
)?;
for value in row {
output_file.write_all(b",")?;
output_file.write_all(value.as_bytes())?;
}
output_file.write_all(b"\n")?;
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment