Update File Symbol, add tests

This commit is contained in:
Adrian Heine 2017-01-28 20:26:33 +01:00
parent 301b39a80a
commit 55f2cfae95
4 changed files with 126 additions and 57 deletions

View file

@ -1,45 +1,13 @@
use std::error::Error;
use std::borrow::Cow;
use std::fmt;
use std::fs::File as FsFile;
use std::io;
use std::io::{Read, Write};
use std::ops::Deref;
use std::path::Path;
use symbols::Symbol;
#[derive(Debug)]
pub enum FileError<E: Error> {
ExecError(E),
GenericError
}
impl From<io::Error> for FileError<io::Error> {
fn from(err: io::Error) -> FileError<io::Error> {
FileError::ExecError(err)
}
}
impl<E: Error> Error for FileError<E> {
fn description(&self) -> &str {
match self {
&FileError::ExecError(ref e) => e.description(),
&FileError::GenericError => "Generic error"
}
}
fn cause(&self) -> Option<&Error> {
match self {
&FileError::ExecError(ref e) => Some(e),
_ => None
}
}
}
impl<E: Error> fmt::Display for FileError<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.description())
}
}
use std::convert::AsRef;
pub struct File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt::Display {
path: D,
content: C
@ -54,11 +22,9 @@ impl<C, D> File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt::Display {
}
}
use std::fs::File as FsFile;
use std::io::{Read, Write};
impl<C, D> Symbol for File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt::Display {
type Error = FileError<io::Error>;
type Error = io::Error;
fn target_reached(&self) -> Result<bool, Self::Error> {
let file = FsFile::open(self.path.as_ref());
// Check if file exists
@ -66,16 +32,20 @@ impl<C, D> Symbol for File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt
return if e.kind() == io::ErrorKind::NotFound {
Ok(false)
} else {
Err(e.into())
Err(e)
};
}
// Check if content is the same
let file_content = file.unwrap().bytes();
let content_equal = try!(self.content.bytes().zip(file_content).fold(
Ok(true),
|state, (target_byte, file_byte_option)| state.and_then(|s| file_byte_option.map(|file_byte| s && file_byte == target_byte))
));
return Ok(content_equal)
let mut file_content = file.unwrap().bytes();
let mut target_content = self.content.bytes();
loop {
match (file_content.next(), target_content.next()) {
(None, None) => return Ok(true),
(Some(Ok(a)), Some(b)) if a == b => {},
(Some(Err(e)), _) => return Err(e),
(_, _) => return Ok(false)
}
}
}
fn execute(&self) -> Result<(), Self::Error> {
@ -86,7 +56,7 @@ impl<C, D> Symbol for File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt
}
impl<C, D> fmt::Display for File<C, D> where C: Deref<Target=str>, D: AsRef<str> + fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(),fmt::Error>{
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
write!(f, "File {}", self.path)
}
}

View file

@ -6,7 +6,6 @@ use std::ops::Deref;
use command_runner::CommandRunner;
use symbols::Symbol;
use symbols::file::File as FileSymbol;
use symbols::file::FileError;
#[derive(Debug)]
pub enum NginxServerError<E: Error> {
@ -14,18 +13,12 @@ pub enum NginxServerError<E: Error> {
GenericError
}
impl<E: Error> From<FileError<E>> for NginxServerError<FileError<E>> {
fn from(err: FileError<E>) -> NginxServerError<FileError<E>> {
impl From<io::Error> for NginxServerError<io::Error> {
fn from(err: io::Error) -> NginxServerError<io::Error> {
NginxServerError::ExecError(err)
}
}
impl<E: Error> From<io::Error> for NginxServerError<FileError<E>> {
fn from(err: io::Error) -> NginxServerError<FileError<E>> {
NginxServerError::GenericError
}
}
impl<E: Error> Error for NginxServerError<E> {
fn description(&self) -> &str {
match self {