|
|
@ -1,6 +1,6 @@ |
|
|
|
use super::runnable::Runnable;
|
|
|
|
use super::util::{AddResult, AddableResource};
|
|
|
|
use super::Setup;
|
|
|
|
use super::setup::Setup;
|
|
|
|
use super::util::{AddableResource, InternalAddResult};
|
|
|
|
use super::SymbolRunner;
|
|
|
|
use crate::async_utils::try_join;
|
|
|
|
use crate::loggers::{Logger, StoringLogger};
|
|
|
@ -16,15 +16,15 @@ use std::marker::PhantomData; |
|
|
|
|
|
|
|
#[async_trait(?Send)]
|
|
|
|
pub trait AddGeneric<X: ToArtifact> {
|
|
|
|
async fn add_generic(&self, x: X) -> AddResult<X>;
|
|
|
|
async fn add_generic(&self, x: X) -> InternalAddResult<X>;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! add_generic {
|
|
|
|
( $($name:ident)* ) => (
|
|
|
|
#[async_trait(?Send)]
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
impl<SR: 'static, _L: 'static, _B: 'static, LOG: 'static + Logger, Rs: 'static + Hash + Eq, As: 'static + Clone, $($name: AddableResource,)*>
|
|
|
|
AddGeneric<($($name,)*)> for Setup<SR, LOG, _L, _B, Rs, As>
|
|
|
|
impl<SR: 'static, _L: 'static, _B: 'static, Rs: 'static + Hash + Eq, As: 'static + Clone, $($name: AddableResource,)*>
|
|
|
|
AddGeneric<($($name,)*)> for Setup<SR, _L, _B, Rs, As>
|
|
|
|
where
|
|
|
|
$(
|
|
|
|
RegularSetupCore<SR, _L, _B>: SetupCore<$name, Self>,
|
|
|
@ -34,11 +34,13 @@ macro_rules! add_generic { |
|
|
|
),*
|
|
|
|
{
|
|
|
|
#[allow(unused)]
|
|
|
|
async fn add_generic(&self, ($($name,)*): ($($name,)*)) -> Result<(($($name::Artifact,)*), bool), Box<dyn Error>>
|
|
|
|
async fn add_generic(&self, ($($name,)*): ($($name,)*)) -> Result<(StoringLogger, ($($name::Artifact,)*), bool), (StoringLogger, Box<dyn Error>)>
|
|
|
|
{
|
|
|
|
let x: Result<_, Box<dyn Error>> = try_join!($(self.add_force($name, false),)*);
|
|
|
|
let x: Result<_, _> = try_join!($(self.add($name, false),)*);
|
|
|
|
let ($($name,)*) = x?;
|
|
|
|
Ok((($($name.0,)*), false $(|| $name.1)*))
|
|
|
|
let logger = StoringLogger::default();
|
|
|
|
$(logger.put($name.0.release());)*
|
|
|
|
Ok((logger, ($($name.1,)*), false $(|| $name.2)*))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
@ -51,57 +53,54 @@ for_each_tuple!(add_generic); |
|
|
|
#[async_trait(?Send)]
|
|
|
|
impl<
|
|
|
|
SR: 'static + SymbolRunner,
|
|
|
|
LOG: 'static + Logger,
|
|
|
|
T: AddableResource,
|
|
|
|
Rs: 'static + Hash + Eq + FromResource<T>,
|
|
|
|
As: 'static + FromArtifact<T> + Clone,
|
|
|
|
L: 'static + ResourceLocator<T, Prerequisites = Option<T>>,
|
|
|
|
B: 'static + ImplementationBuilder<T>,
|
|
|
|
> AddGeneric<Option<T>> for Setup<SR, LOG, L, B, Rs, As>
|
|
|
|
> AddGeneric<Option<T>> for Setup<SR, L, B, Rs, As>
|
|
|
|
where
|
|
|
|
<B as ImplementationBuilder<T>>::Implementation: Runnable + Debug,
|
|
|
|
Self: AddGeneric<B::Prerequisites>,
|
|
|
|
T::Artifact: Clone,
|
|
|
|
{
|
|
|
|
async fn add_generic(&self, r: Option<T>) -> AddResult<Option<T>> {
|
|
|
|
async fn add_generic(&self, r: Option<T>) -> InternalAddResult<Option<T>> {
|
|
|
|
Ok(match r {
|
|
|
|
Some(r) => {
|
|
|
|
let (result, did_run) = self.add_force(r, false).await?;
|
|
|
|
(Some(result), did_run)
|
|
|
|
let (logger, result, did_run) = self.add(r, false).await?;
|
|
|
|
(logger, Some(result), did_run)
|
|
|
|
}
|
|
|
|
None => (None, false),
|
|
|
|
None => (StoringLogger::default(), None, false),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait(?Send)]
|
|
|
|
impl<
|
|
|
|
LOG: 'static + Logger,
|
|
|
|
T: AddableResource,
|
|
|
|
Rs: 'static + Hash + Eq + FromResource<T>,
|
|
|
|
As: 'static + FromArtifact<T> + Clone,
|
|
|
|
SR: 'static,
|
|
|
|
L: 'static,
|
|
|
|
B: 'static,
|
|
|
|
> AddGeneric<T> for Setup<SR, LOG, L, B, Rs, As>
|
|
|
|
> AddGeneric<T> for Setup<SR, L, B, Rs, As>
|
|
|
|
where
|
|
|
|
T::Artifact: Clone,
|
|
|
|
RegularSetupCore<SR, L, B>: 'static + SetupCore<T, Self>,
|
|
|
|
{
|
|
|
|
async fn add_generic(&self, r: T) -> AddResult<T> {
|
|
|
|
self.add_force(r, false).await
|
|
|
|
async fn add_generic(&self, r: T) -> InternalAddResult<T> {
|
|
|
|
self.add(r, false).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait(?Send)]
|
|
|
|
pub trait SetupCore<R: AddableResource, S> {
|
|
|
|
async fn add<LOG: Logger, RR: AsRef<R>>(
|
|
|
|
async fn add<RR: AsRef<R>>(
|
|
|
|
&self,
|
|
|
|
setup: &S,
|
|
|
|
parent_logger: &LOG,
|
|
|
|
resource: RR,
|
|
|
|
force_run: bool,
|
|
|
|
) -> AddResult<R>;
|
|
|
|
) -> InternalAddResult<R>;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
@ -127,49 +126,57 @@ where |
|
|
|
L: ResourceLocator<R>,
|
|
|
|
S: AddGeneric<B::Prerequisites> + AddGeneric<<L as ResourceLocator<R>>::Prerequisites>,
|
|
|
|
{
|
|
|
|
async fn add<LOG: Logger, RR: AsRef<R>>(
|
|
|
|
async fn add<RR: AsRef<R>>(
|
|
|
|
&self,
|
|
|
|
setup: &S,
|
|
|
|
parent_logger: &LOG,
|
|
|
|
resource: RR,
|
|
|
|
force_run: bool,
|
|
|
|
) -> AddResult<R> {
|
|
|
|
) -> InternalAddResult<R> {
|
|
|
|
let resource = resource.as_ref();
|
|
|
|
let logger = StoringLogger::new();
|
|
|
|
logger.write(4, format!("Adding {:?} ... ", resource));
|
|
|
|
let result = async {
|
|
|
|
logger.trace(format!(" (force_run is {})", force_run));
|
|
|
|
let (location, location_prereqs) = L::locate(resource);
|
|
|
|
logger.trace(format!("Adding location prereqs for {:?}", resource));
|
|
|
|
let (_, location_prereqs_did_run) = setup.add_generic(location_prereqs).await?;
|
|
|
|
logger.trace(format!(
|
|
|
|
"Location prereqs for {:?} did_run: {}",
|
|
|
|
resource, location_prereqs_did_run
|
|
|
|
));
|
|
|
|
logger.trace(format!("Adding implementation prereqs for {:?}", resource));
|
|
|
|
let (prereqs, prereqs_did_run) = setup.add_generic(B::prerequisites(resource)).await?;
|
|
|
|
logger.trace(format!(
|
|
|
|
"Implementation prereqs for {:?} did_run: {}",
|
|
|
|
resource, prereqs_did_run
|
|
|
|
));
|
|
|
|
logger.trace(format!("Running implementation for {:?}", resource));
|
|
|
|
let implementation = B::create(resource, &location, prereqs);
|
|
|
|
let did_run = implementation
|
|
|
|
.run(
|
|
|
|
&self.symbol_runner,
|
|
|
|
&logger,
|
|
|
|
force_run || location_prereqs_did_run || prereqs_did_run,
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
Ok((location, did_run))
|
|
|
|
logger.write(4, format!("(force_run is {})", force_run));
|
|
|
|
let (location, location_prereqs) = L::locate(resource);
|
|
|
|
logger.trace(format!("Adding location prereqs for {:?}", resource));
|
|
|
|
let result = setup.add_generic(location_prereqs).await;
|
|
|
|
if let Err((log, e)) = result {
|
|
|
|
logger.put(log.release());
|
|
|
|
return Err((logger, e));
|
|
|
|
}
|
|
|
|
.await;
|
|
|
|
logger.write(4, "done.");
|
|
|
|
let max_level = if result.is_err() { 5 } else { 3 };
|
|
|
|
if parent_logger.put(logger.release().into_iter().filter(|e| e.0 <= max_level)) == 0 {
|
|
|
|
parent_logger.write(3, ".");
|
|
|
|
let (location_prereq_logger, _, location_prereqs_did_run) = result.unwrap();
|
|
|
|
logger.put(location_prereq_logger.release());
|
|
|
|
logger.trace(format!(
|
|
|
|
"Location prereqs for {:?} did_run: {}",
|
|
|
|
resource, location_prereqs_did_run
|
|
|
|
));
|
|
|
|
logger.trace(format!("Adding implementation prereqs for {:?}", resource));
|
|
|
|
let result = setup.add_generic(B::prerequisites(resource)).await;
|
|
|
|
if let Err((log, e)) = result {
|
|
|
|
logger.put(log.release());
|
|
|
|
return Err((logger, e));
|
|
|
|
}
|
|
|
|
let (impl_prereq_logger, prereqs, prereqs_did_run) = result.unwrap();
|
|
|
|
logger.put(impl_prereq_logger.release());
|
|
|
|
logger.trace(format!(
|
|
|
|
"Implementation prereqs for {:?} did_run: {}",
|
|
|
|
resource, prereqs_did_run
|
|
|
|
));
|
|
|
|
logger.trace(format!("Running implementation for {:?}", resource));
|
|
|
|
let implementation = B::create(resource, &location, prereqs);
|
|
|
|
let did_run_result = implementation
|
|
|
|
.run(
|
|
|
|
&self.symbol_runner,
|
|
|
|
&logger,
|
|
|
|
force_run || location_prereqs_did_run || prereqs_did_run,
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
match did_run_result {
|
|
|
|
Ok(did_run) => {
|
|
|
|
logger.write(4, "done.");
|
|
|
|
Ok((logger, location, did_run))
|
|
|
|
}
|
|
|
|
Err(e) => Err((logger, e)),
|
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|