Skip to content

Instantly share code, notes, and snippets.

@Thiez
Forked from steveklabnik/main.rs
Created October 26, 2017 10:40
Show Gist options
  • Save Thiez/b3fa48fb0fac2a273ea1f56cc0fd692b to your computer and use it in GitHub Desktop.
Save Thiez/b3fa48fb0fac2a273ea1f56cc0fd692b to your computer and use it in GitHub Desktop.
The Results of the Expressive C++17 Coding Challenge in Rust
use std::io::{Read, Write};
use std::fs::File;
fn main() {
let args = ::std::env::args().collect::<Vec<_>>();
// skip the program name
if args.len() != 5 {
println!("Usage: {} <filename> <columnname> <replacement> <output_filename>", args[0]);
}
let filename = &args[1];
let column_name = &args[2];
let replacement = &args[3];
let output_filename = &args[4];
load_csv(filename)
.and_then(|csv_data|replace_column(&csv_data, column_name, replacement))
.and_then(|modified_data|write_csv(&modified_data, output_filename))
.unwrap();
}
fn load_csv(filename: &str) -> Result<String, &'static str> {
let mut buffer = String::new();
File::open(filename)
.ok()
.into_iter()
.flat_map(|mut f|f.read_to_string(&mut buffer).ok())
.filter(|&n| n > 0)
.next().map(|_|buffer).ok_or("input file missing")
}
fn replace_column(data: &str, column: &str, replacement: &str) -> Result<String, &'static str> {
let mut lines = data.lines();
lines.next()
.ok_or("no first line!")
.and_then(|c|c.split(',').position(|e|e == column).map(|pos|(c, pos)).ok_or("column name doesn't exist in the input file"))
.map(|(c, pos)|lines.fold(c.to_owned() + "\n", |mut res, line| {
res.extend(line.split(',')
.enumerate()
.map(|(i, val)|if pos == i { replacement } else { val }));
res.push_str("\n");
res
}))
}
fn write_csv(data: &str, filename: &str) -> Result<(), &'static str> {
File::create(filename)
.ok()
.and_then(|mut f| f.write_all(data.as_bytes()).ok())
.ok_or("Could not write to file!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment