Skip to content

Instantly share code, notes, and snippets.

Created October 25, 2017 16:06
Show Gist options
  • Save steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5 to your computer and use it in GitHub Desktop.
Save steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5 to your computer and use it in GitHub Desktop.
The Results of the Expressive C++17 Coding Challenge in Rust
use std::env;
use std::io;
use std::io::prelude::*;
use std::fs::File;
enum Error {
Program(&'static str),
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
impl From<&'static str> for Error {
fn from(e: &'static str) -> Error {
fn main() {
let mut args = env::args();
// skip the program name;
let filename =;
let column_name =;
let replacement =;
let output_filename =;
let csv_data = load_csv(&filename).unwrap();
let modified_data = replace_column(csv_data, &column_name, &replacement).unwrap();
write_csv(&modified_data, &output_filename).unwrap();
fn load_csv(filename: &str) -> Result<String, Error> {
let mut f = File::open(filename)?;
let mut buffer = String::new();
f.read_to_string(&mut buffer)?;
if buffer.is_empty() {
return Err("input file missing")?
fn replace_column(data: String, column: &str, replacement: &str) -> Result<String, Error> {
let mut lines = data.lines();
let columns =;
let columns: Vec<&str> = columns.split(',').collect();
let column_number = columns.iter().position(|&e| e == column);
let column_number = match column_number {
Some(column) => column,
None => Err("column name doesn’t exist in the input file")?
let mut result = String::with_capacity(data.capacity());
for line in lines {
let mut records: Vec<&str> = line.split(',').collect();
records[column_number] = replacement;
fn write_csv(data: &str, filename: &str) -> Result<(), Error> {
let mut buffer = File::create(filename)?;
Copy link

Beautiful !!!

Copy link

locka99 commented Oct 26, 2017

Looks a lot more readable than the winning C++17 entry

Copy link

Nice, yet I have to nitpick that the winning C++ entry does not load the entire input file into memory. Wrapping the file into a std::io::BufReader instead of saving it to a string would do the trick, since BufRead also exposes a lines() iterator.

Copy link

msehnout commented Nov 1, 2017

I like some aspects of the C++ version more, so I decided to combine them into my own version. Also there is a problem, that the winning entry does not respect the rule In both cases, there shouldn’t be any output file generated.. I decided to obey this rule, although it makes the code less nice, because of the split of the get_file_handlers function.

Copy link

boxdot commented Nov 4, 2017

@msehnout: I totally agree that for big csv it could a problem to read everything into memory. Another issue could be: not necessary mallocs inside the iteratation over the lines. Actually, there is no need for creating any temporary vectors or strings at all:

I was too lazy to define From impls, which definitely a better approach than using String as universal error wrapper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment