#[macro_use]
extern crate snafu;
extern crate serde_json;
extern crate structopt;
extern crate xio_webapi;
use snafu::{Backtrace, ResultExt};
use std::fs::File;
use std::io::{BufRead, BufReader};
use structopt::StructOpt;
use xio_webapi::JobEvent;
#[derive(Debug, Snafu)]
enum Error {
#[snafu(display("Deserialization failed {}", source))]
LineDeserialization {
source: serde_json::Error,
backtrace: Backtrace,
},
#[snafu(display("Couldn't open file {}: {}", path.display(), source))]
FileOpen {
path: std::path::PathBuf,
source: std::io::Error,
backtrace: Backtrace,
},
#[snafu(display("Couldn't read from file {}: {}", path.display(), source))]
FileRead {
path: std::path::PathBuf,
source: std::io::Error,
backtrace: Backtrace,
},
}
type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(StructOpt, Debug)]
#[structopt(name = "xio-check-joblog")]
struct Arguments {
file: String,
}
fn load_line(line: &str) -> Result<JobEvent> {
serde_json::from_str(line).context(LineDeserialization {})
}
fn check_line(number: usize, line: &str) -> usize {
match load_line(line) {
Ok(_) => 0usize,
Err(e) => {
eprintln!("Error in line {}: {}", number, e,);
1usize
}
}
}
fn run() -> Result<usize> {
let arguments = Arguments::from_args();
println!("Checking file {}", arguments.file);
let path = std::path::PathBuf::from(arguments.file);
let file = File::open(&path).context(FileOpen {
path: path.to_path_buf(),
})?;
let mut count = 0usize;
for (number, line) in BufReader::new(file).lines().enumerate() {
count += check_line(
number + 1,
&line.context(FileRead {
path: path.to_path_buf(),
})?,
);
}
if count == 0usize {
println!("File OK");
} else {
println!("Found {} errors", count);
}
Ok(count)
}
fn main() -> Result<()> {
use std::process::exit;
let res = run();
match &res {
Ok(c) if *c == 0usize => exit(0),
Ok(_) => exit(1),
Err(_) => {}
};
res.map(|_| ())
}