use std::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
#[derive(Debug, Clone, Default)]
pub struct BuildContext {
pub success: bool,
pub duration: Duration,
pub warnings: Vec<String>,
pub errors: Vec<String>,
}
#[derive(Debug, Clone, Default)]
pub struct TestContext {
pub passed: bool,
pub passed_count: usize,
pub failed_count: usize,
pub skipped_count: usize,
pub duration: Duration,
}
#[derive(Debug, Clone)]
pub struct PluginContext {
pub project_root: PathBuf,
pub project_name: String,
pub ghc_version: Option<String>,
pub cabal_file: Option<PathBuf>,
pub build: Option<BuildContext>,
pub test: Option<TestContext>,
pub env_vars: HashMap<String, String>,
pub verbose: bool,
}
impl PluginContext {
pub fn new(project_root: PathBuf, project_name: String) -> Self {
PluginContext {
project_root,
project_name,
ghc_version: None,
cabal_file: None,
build: None,
test: None,
env_vars: HashMap::new(),
verbose: false,
}
}
pub fn with_ghc_version(mut self, version: impl Into<String>) -> Self {
self.ghc_version = Some(version.into());
self
}
pub fn with_cabal_file(mut self, path: impl Into<PathBuf>) -> Self {
self.cabal_file = Some(path.into());
self
}
pub fn with_build_context(mut self, build: BuildContext) -> Self {
self.build = Some(build);
self
}
pub fn with_test_context(mut self, test: TestContext) -> Self {
self.test = Some(test);
self
}
pub fn with_verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
pub fn set_env(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.env_vars.insert(key.into(), value.into());
}
}
thread_local! {
static CONTEXT: RefCell<Option<PluginContext>> = const { RefCell::new(None) };
}
pub fn set_context(ctx: PluginContext) {
CONTEXT.with(|c| {
*c.borrow_mut() = Some(ctx);
});
}
pub fn clear_context() {
CONTEXT.with(|c| {
*c.borrow_mut() = None;
});
}
pub fn with_context<F, R>(f: F) -> Option<R>
where
F: FnOnce(&PluginContext) -> R,
{
CONTEXT.with(|c| c.borrow().as_ref().map(f))
}
pub fn with_context_mut<F, R>(f: F) -> Option<R>
where
F: FnOnce(&mut PluginContext) -> R,
{
CONTEXT.with(|c| c.borrow_mut().as_mut().map(f))
}
pub struct ContextGuard;
impl ContextGuard {
pub fn new(ctx: PluginContext) -> Self {
set_context(ctx);
ContextGuard
}
}
impl Drop for ContextGuard {
fn drop(&mut self) {
clear_context();
}
}