diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-26 11:52:55 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-26 11:52:55 +0000 |
commit | a7af9cc3b7eff7e61c4d627dbea943eef8ea664f (patch) | |
tree | d0144d1bdd94ef1e0818594fe2bb23f05a19e1e5 /subplotlib | |
parent | 3f16e21541f2171846b8fa330a9f7b8886363fd9 (diff) | |
download | subplot-a7af9cc3b7eff7e61c4d627dbea943eef8ea664f.tar.gz |
subplotlib: Add ContextElement trait
In order to begin to permit context elements to handle step
changes etc, this introduces a trait which can be used to
track scenarios.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'subplotlib')
-rw-r--r-- | subplotlib/src/scenario.rs | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/subplotlib/src/scenario.rs b/subplotlib/src/scenario.rs index ec3f28f..f3b8dce 100644 --- a/subplotlib/src/scenario.rs +++ b/subplotlib/src/scenario.rs @@ -11,27 +11,61 @@ use state::Container; use crate::step::ScenarioStep; use crate::types::{StepError, StepResult}; +/// A context element is anything which can be used as a scenario step context. +/// +/// Contexts get called whenever the scenario steps occur so that they can do +/// prep, cleanup, etc. It's important for authors of context element types to +/// be aware that they won't always be called on scenario start and they will +/// not be caught up the first time they are invoked for a step, simply expected +/// to get on with life from their first use. +pub trait ContextElement: Send + 'static { + /// Create a context element. + /// + /// In order to permit elements which for example work on disk, this + /// function will be invoked with the scenario's name to permit the creation + /// of suitably named temporary directories, logging, etc. + /// + /// There will be an impl of this for Default capable types should the name + /// be unnecessary. + fn create(scenario_title: &str) -> Self; +} + +impl<T> ContextElement for T +where + T: Default + Send + 'static, +{ + fn create(_scenario_title: &str) -> Self { + Self::default() + } +} /// A scenario context wrapper for a particular context type struct ScenarioContextItem<C>(Mutex<C>); /// A container for all scenario contexts /// /// This container allows the running of code within a given scenario context. pub struct ScenarioContext { + title: String, inner: Container, } impl ScenarioContext { - fn new() -> Self { + fn new(title: &str) -> Self { Self { + title: title.to_string(), inner: Container::new(), } } + /// The title for this scenario + fn title(&self) -> &str { + &self.title + } + /// With the extracted immutable context, run the function f. pub fn with<C, F>(&self, func: F, defuse_poison: bool) -> StepResult where F: FnOnce(&C) -> StepResult, - C: Default + Send + 'static, + C: ContextElement, { self.with_mut(|c: &mut C| func(&*c), defuse_poison) } @@ -40,13 +74,13 @@ impl ScenarioContext { pub fn with_mut<C, F>(&self, func: F, defuse_poison: bool) -> StepResult where F: FnOnce(&mut C) -> StepResult, - C: Default + Send + 'static, + C: ContextElement, { let sci: &ScenarioContextItem<C> = if let Some(sci) = self.inner.try_get() { sci } else { self.inner - .set(ScenarioContextItem(Mutex::new(C::default()))); + .set(ScenarioContextItem(Mutex::new(C::create(&self.title)))); self.inner.get() }; let mut lock = match sci.0.lock() { @@ -69,7 +103,6 @@ impl ScenarioContext { /// to completion. In rare cases they may be built up and cached for reuse /// for example if a scenario is a subroutine. pub struct Scenario { - title: String, contexts: ScenarioContext, steps: Vec<(ScenarioStep, Option<ScenarioStep>)>, } @@ -78,15 +111,14 @@ impl Scenario { /// Create a new scenario with the given title pub fn new(title: &str) -> Self { Self { - title: title.to_string(), - contexts: ScenarioContext::new(), + contexts: ScenarioContext::new(title), steps: Vec::new(), } } /// Retrieve the scenario title pub fn title(&self) -> &str { - &self.title + self.contexts.title() } /// Add a scenario step, with optional cleanup step function. |