summaryrefslogtreecommitdiff
path: root/subplotlib
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-12-26 11:52:55 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-12-26 11:52:55 +0000
commita7af9cc3b7eff7e61c4d627dbea943eef8ea664f (patch)
treed0144d1bdd94ef1e0818594fe2bb23f05a19e1e5 /subplotlib
parent3f16e21541f2171846b8fa330a9f7b8886363fd9 (diff)
downloadsubplot-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.rs48
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.