#[cfg(feature = "use_failure")]
#[macro_use] extern crate failure_derive;
#[cfg(feature = "use_failure")]
use std::io;
use std::{
path::Path,
fs::File,
io::{
Read,
Write,
}
};
pub trait FromFile : Sized {
#[cfg(feature = "use_failure")]
fn from_file(path: &Path) -> Result<Self, Failure> {
let mut file_handle = match File::open(path) {
Ok(handle) => handle,
Err(cause) => return Err(Failure::FileOpenError { cause }),
};
let mut file_contents = Vec::new();
match file_handle.read_to_end(&mut file_contents) {
Ok(_i) => (),
Err(cause) => return Err(Failure::FileReadError { cause }),
}
match Self::deserialize(&file_contents) {
Ok(data) => Ok(data),
Err(cause) => Err(Failure::DeserializationError { cause }),
}
}
#[cfg(not(feature = "use_failure"))]
fn from_file(path: &Path) -> Result<Self, String> {
let mut file_handle = match File::open(path) {
Ok(handle) => handle,
Err(cause) => return Err(String::from(format!("failed to open file: {}", cause))),
};
let mut file_contents = Vec::new();
match file_handle.read_to_end(&mut file_contents) {
Ok(_i) => (),
Err(cause) => return Err(String::from(format!("failed to read file: {}", cause))),
}
match Self::deserialize(&file_contents) {
Ok(data) => Ok(data),
Err(cause) => Err(String::from(format!("failed to create file: {}", cause))),
}
}
#[cfg(feature = "use_failure")]
fn deserialize(data: &Vec<u8>) -> Result<Self, failure::Error>;
#[cfg(not(feature = "use_failure"))]
fn deserialize(data: &Vec<u8>) -> Result<Self, String>;
}
pub trait ToFile : Sized {
#[cfg(feature = "use_failure")]
fn to_file(&self, path: &Path) -> Result<(), Failure> {
let mut file_handle = match File::create(path){
Ok(handle) => handle,
Err(cause) => return Err(Failure::FileOpenError { cause }),
};
let mut file_contents = match self.serialize() {
Ok(bytes) => bytes,
Err(cause) => return Err(Failure::SerializationError { cause }),
};
match file_handle.write_all(&mut file_contents) {
Ok(()) => (),
Err(cause) => return Err(Failure::FileWriteError { cause }),
}
match file_handle.flush() {
Ok(()) => Ok(()),
Err(cause) => Err(Failure::FileFlushError { cause }),
}
}
#[cfg(not(feature = "use_failure"))]
fn to_file(&self, path: &Path) -> Result<(), String> {
let mut file_handle = match File::create(path){
Ok(handle) => handle,
Err(cause) => return Err(String::from(format!("failed to create file: {}", cause))),
};
let mut file_contents = match self.serialize() {
Ok(bytes) => bytes,
Err(cause) => return Err(String::from(format!("failed to serialize data: {}", cause))),
};
match file_handle.write_all(&mut file_contents) {
Ok(()) => (),
Err(cause) => return Err(String::from(format!("failed to serialize data: {}", cause))),
}
match file_handle.flush() {
Ok(()) => Ok(()),
Err(cause) => Err(String::from(format!("failed to serialize data: {}", cause))),
}
}
#[cfg(feature = "use_failure")]
fn serialize(&self) -> Result<Vec<u8>, failure::Error>;
#[cfg(not(feature = "use_failure"))]
fn serialize(&self) -> Result<Vec<u8>, String>;
}
#[cfg(feature = "use_failure")]
#[derive(Debug, Fail)]
pub enum Failure {
#[fail(display = "error flushing to file: {}", cause)]
FileFlushError {
#[cause] cause: io::Error,
},
#[fail(display = "error opening file: {}", cause)]
FileOpenError {
#[cause] cause: io::Error,
},
#[fail(display = "error reading from file: {}", cause)]
FileReadError {
#[cause] cause: io::Error,
},
#[fail(display = "error writing to file: {}", cause)]
FileWriteError {
#[cause] cause: io::Error,
},
#[fail(display = "error deserializing data: {}", cause)]
DeserializationError {
#[cause] cause: failure::Error,
},
#[fail(display = "error serializing data: {}", cause)]
SerializationError {
#[cause] cause: failure::Error,
},
}