I never liked program that show 1 error, you fix it you run it again, it shows another error and so on. For my programs i like to collect as many errors as possible and show them all. I have the following program:
extern crate clap;
extern crate yansi;
extern crate serde_json;
use clap::{Arg, App};
use std::fs::File;
use yansi::Paint;
use serde_json::{Value, Error};
fn main() {
// https://github.com/clap-rs/clap#quick-example
let matches = App::new("json")
.arg(Arg::with_name("first file")
.index(1)
.required(true))
.arg(Arg::with_name("second file")
.index(2)
.required(true))
.get_matches();
let fp_a = File::open(matches.value_of("first file").unwrap());
let fp_b = File::open(matches.value_of("second file").unwrap());
// https://stackoverflow.com/a/27590832
// https://docs.rs/yansi/0.4.0/yansi/
if fp_a.is_err() {
eprintln!("{}", Paint::red("First file could not be found or opened."));
}
if fp_b.is_err() {
eprintln!("{}", Paint::red("Second file could not be found or opened."));
}
if fp_a.is_ok() {
let v_a: Result<Value, Error> = serde_json::from_reader(fp_a.as_ref().unwrap());
if v_a.is_err() {
eprintln!("{}", Paint::red("First file is not a valid json file."));
}
}
if fp_b.is_ok() {
let v_b: Result<Value, Error> = serde_json::from_reader(fp_b.as_ref().unwrap());
if v_b.is_err() {
eprintln!("{}", Paint::red("Second file is not a valid json file."));
}
}
if fp_a.is_err() || fp_b.is_err() || v_a.is_err() || v_b.is_err() {
eprintln!("{}", Paint::red("Aborting due to previous errors."));
}
println!("Rest of program with valid input ..");
}
The problem is that here fp_a.is_err() || fp_b.is_err() || v_a.is_err() || v_b.is_err() v_a and v_b are not in scope. I tried moving code around in all sorts of different ways, but it creates other problems.
If i only had file A it would have been easy because i can keep nesting if-else blocks. But since i have two files this is not possible. Each file sets in motion a chain of error checks. Only two are shown here: 1. can file be opened 2. is it valid json. But i might add more later. Is there some error collecting mechanism (monad ??) of some sorts? I think the code as it is now is kind of ugly with all the is_err() and is_ok() function calls.