|
|
@ -1,9 +1,10 @@ |
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::error::Error;
|
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
use loggers::Logger;
|
|
|
|
use repository::SymbolRepository;
|
|
|
|
use symbols::Symbol;
|
|
|
|
use symbols::{Symbol, SymbolRunner};
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum SymbolRunError {
|
|
|
@ -35,15 +36,20 @@ impl fmt::Display for SymbolRunError { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait SymbolRunner {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>;
|
|
|
|
pub struct InitializingSymbolRunner<L: Logger> {
|
|
|
|
logger: RefCell<L>
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct InitializingSymbolRunner;
|
|
|
|
impl<L: Logger> InitializingSymbolRunner<L> {
|
|
|
|
pub fn new(logger: L) -> Self {
|
|
|
|
Self { logger: RefCell::new(logger) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SymbolRunner for InitializingSymbolRunner {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>
|
|
|
|
impl<L: Logger> SymbolRunner for InitializingSymbolRunner<L> {
|
|
|
|
fn run_symbol(&self, symbol: &Symbol) -> Result<(), Box<Error>>
|
|
|
|
{
|
|
|
|
let mut logger = self.logger.borrow_mut();
|
|
|
|
let target_reached = try!(symbol.target_reached());
|
|
|
|
if target_reached {
|
|
|
|
logger.write(format!("{} already reached", symbol).as_str());
|
|
|
@ -61,11 +67,20 @@ impl SymbolRunner for InitializingSymbolRunner { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct DrySymbolRunner;
|
|
|
|
pub struct DrySymbolRunner<L: Logger> {
|
|
|
|
logger: RefCell<L>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SymbolRunner for DrySymbolRunner {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>
|
|
|
|
impl<L: Logger> DrySymbolRunner<L> {
|
|
|
|
pub fn new(logger: L) -> Self {
|
|
|
|
Self { logger: RefCell::new(logger) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<L: Logger> SymbolRunner for DrySymbolRunner<L> {
|
|
|
|
fn run_symbol(&self, symbol: &Symbol) -> Result<(), Box<Error>>
|
|
|
|
{
|
|
|
|
let mut logger = self.logger.borrow_mut();
|
|
|
|
let target_reached = try!(symbol.target_reached());
|
|
|
|
logger.debug(format!("Symbol reports target_reached: {:?}", target_reached).as_str());
|
|
|
|
if !target_reached {
|
|
|
@ -75,19 +90,20 @@ impl SymbolRunner for DrySymbolRunner { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ReportingSymbolRunner<'a, R: 'a + SymbolRunner>(&'a R);
|
|
|
|
pub struct ReportingSymbolRunner<'a, R: 'a + SymbolRunner, L: Logger>(&'a R, RefCell<L>);
|
|
|
|
|
|
|
|
impl<'a, R> ReportingSymbolRunner<'a, R> where R: SymbolRunner {
|
|
|
|
pub fn new(symbol_runner: &'a R) -> Self {
|
|
|
|
ReportingSymbolRunner(symbol_runner)
|
|
|
|
impl<'a, R, L> ReportingSymbolRunner<'a, R, L> where R: SymbolRunner, L: Logger {
|
|
|
|
pub fn new(symbol_runner: &'a R, logger: L) -> Self {
|
|
|
|
ReportingSymbolRunner(symbol_runner, RefCell::new(logger))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, R> SymbolRunner for ReportingSymbolRunner<'a, R> where R: SymbolRunner {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>
|
|
|
|
impl<'a, R, L> SymbolRunner for ReportingSymbolRunner<'a, R, L> where R: SymbolRunner, L: Logger {
|
|
|
|
fn run_symbol(&self, symbol: &Symbol) -> Result<(), Box<Error>>
|
|
|
|
{
|
|
|
|
let mut logger = self.1.borrow_mut();
|
|
|
|
logger.debug(format!("Running symbol {}", symbol).as_str());
|
|
|
|
let res = self.0.run_symbol(logger, symbol);
|
|
|
|
let res = self.0.run_symbol(symbol);
|
|
|
|
match &res {
|
|
|
|
&Err(ref e) => {
|
|
|
|
logger.write(format!("Failed on {} with {}, aborting.", symbol, e).as_str());
|
|
|
@ -100,7 +116,6 @@ impl<'a, R> SymbolRunner for ReportingSymbolRunner<'a, R> where R: SymbolRunner |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::collections::HashSet;
|
|
|
|
use resources::Resource;
|
|
|
|
|
|
|
@ -116,7 +131,7 @@ impl<'a, R> NonRepeatingSymbolRunner<'a, R> where R: SymbolRunner { |
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, R> SymbolRunner for NonRepeatingSymbolRunner<'a, R> where R: SymbolRunner {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>
|
|
|
|
fn run_symbol(&self, symbol: &Symbol) -> Result<(), Box<Error>>
|
|
|
|
{
|
|
|
|
if let Some(resources) = symbol.provides() {
|
|
|
|
let mut done = self.done.borrow_mut();
|
|
|
@ -131,7 +146,7 @@ impl<'a, R> SymbolRunner for NonRepeatingSymbolRunner<'a, R> where R: SymbolRunn |
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.upstream.run_symbol(logger, &*symbol)
|
|
|
|
self.upstream.run_symbol(&*symbol)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
use std::marker::PhantomData;
|
|
|
@ -145,14 +160,14 @@ impl<'a, 's, R, G> RequirementsResolvingSymbolRunner<'a, 's, R, G> where R: Symb |
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 's, R, G> SymbolRunner for RequirementsResolvingSymbolRunner<'a, 's, R, G> where R: SymbolRunner, G: SymbolRepository<'s> {
|
|
|
|
fn run_symbol<S: ?Sized + Symbol + fmt::Display>(&self, logger: &mut Logger, symbol: &S) -> Result<(), Box<Error>>
|
|
|
|
fn run_symbol(&self, symbol: &Symbol) -> Result<(), Box<Error>>
|
|
|
|
{
|
|
|
|
for resource in symbol.get_prerequisites() {
|
|
|
|
if let Some(dep) = self.1.get_symbol(&resource) {
|
|
|
|
try!(self.run_symbol(logger, &*dep));
|
|
|
|
try!(dep.as_action(self).run());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.0.run_symbol(logger, &*symbol)
|
|
|
|
self.0.run_symbol(&*symbol)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|