extern crate rustc_serialize;
use rustc_serialize::{json, Decodable, Encodable};
use std::fs::File;
use std::io;
use std::path::Path;
#[derive(Debug)]
pub enum Error {
IO(std::io::Error),
JsonParserError(json::ParserError),
JsonDecoderError(json::DecoderError),
JsonEncoderError(json::EncoderError),
}
impl ::std::fmt::Display for Error {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
writeln!(f, "{:?}", *self)
}
}
impl ::std::error::Error for Error {
fn description(&self) -> &str {
use std::error::Error as StdError;
match *self {
Error::IO(ref err) => err.description(),
Error::JsonParserError(ref err) => err.description(),
Error::JsonDecoderError(ref err) => err.description(),
Error::JsonEncoderError(ref err) => err.description(),
}
}
}
pub fn load<T: Decodable>(path: &Path) -> Result<T, Error> {
let mut file = match File::open(&path) {
Ok(file) => file,
Err(err) => {
match err.kind() {
std::io::ErrorKind::NotFound => {
let mut path = path.to_path_buf();
path.set_extension("json");
try!(File::open(&path).map_err(|err| Error::IO(err)))
},
_ => return Err(Error::IO(err)),
}
},
};
let mut contents = Vec::new();
try!(io::Read::read_to_end(&mut file, &mut contents).map_err(|err| Error::IO(err)));
let json_object = try!(json::Json::from_str(std::str::from_utf8(&contents[..]).unwrap())
.map_err(|err| Error::JsonParserError(err)));
let mut decoder = json::Decoder::new(json_object);
T::decode(&mut decoder).map_err(|err| Error::JsonDecoderError(err))
}
pub fn save<T: Encodable>(path: &Path, t: &T) -> Result<(), Error> {
let mut path = path.to_path_buf();
path.set_extension("json");
let json_string = try!(json::encode(&t).map_err(|err| Error::JsonEncoderError(err)));
let mut file = try!(File::create(&path).map_err(|err| Error::IO(err)));
io::Write::write_all(&mut file, json_string.as_bytes()).map_err(|err| Error::IO(err))
}