Skip to content

Instantly share code, notes, and snippets.

@msehnout
Last active November 2, 2017 13:45
Embed
What would you like to do?
C++17 Coding Challenge in Rust
/*
* # C++17 Coding challenge in Rust
* How to deal with edge cases:
* * if the input file is empty, the program should write “input file missing” to the console.
* * if the input file does not contain the specified column, the program should write “column name doesn’t exists in the input file” to the console.
*
* The rest was not considered and mercilessly unwrapped.
*/
use std::env;
use std::io::{BufReader, BufWriter};
use std::fs::{File, OpenOptions};
use std::io::prelude::*;
fn print_usage(name: &str) {
println!("Usage: {} [IN_FILE] [COLUMN] [NEW_VALUE] [OUT_FILE]", name);
}
fn run(args: Vec<String>) -> Result<(), &'static str> {
let mut reader = open_input_file(&args[1])?;
let mut header = String::new();
reader.read_line(&mut header).unwrap();
let target_index = get_target_column(&header, &args[2])?;
let mut writer = open_output_file(&args[4])?;
writer.write(&header.as_bytes()).unwrap(); // Forward the header line into the output
process(reader, writer, target_index, &args[3])
}
fn open_input_file(name: &str) -> Result<BufReader<File>, &'static str> {
let input = File::open(name)
.map_err(|_| "input file missing")?;
Ok(BufReader::new(input))
}
fn get_target_column(fst_line: &str, label: &str) -> Result<usize, &'static str>
{
match fst_line.split(',').position(|e| e == label) {
Some(n) => Ok(n),
None => Err("column name doesn’t exists in the input file")
}
}
fn open_output_file(name: &str) -> Result<BufWriter<File>, &'static str> {
let output = OpenOptions::new() // Only after the column is found, open the output file
.write(true)
.create(true)
.truncate(true)
.open(name)
.unwrap(); // There is no requirement on error message for output file
Ok(BufWriter::new(output))
}
fn process(reader: BufReader<File>, mut writer: BufWriter<File>, index: usize, replacement: &str)
-> Result<(), &'static str>
{
for line in reader.lines() {
let line = line.unwrap(); // To make borrow checker happy
let mut records: Vec<&str> = line.split(',').collect();
records[index] = replacement;
writer.write(&records.join(",").as_bytes()).unwrap();
writer.write(b"\n").unwrap();
}
Ok(())
}
fn main() {
let args: Vec<_> = env::args().collect();
if args.len() >= 5 {
if let Err(e) = run(args) {
println!("{}", e)
}
} else {
print_usage(&args[0]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment