use crate::progress::ProgressContext;
use std::cell::RefCell;
thread_local! {
static PROGRESS_CONTEXT: RefCell<Option<ProgressContext>> = const { RefCell::new(None) };
}
pub struct ProgressGuard;
impl Drop for ProgressGuard {
fn drop(&mut self) {
clear_progress_context();
}
}
pub trait TaskProgressExt {
fn progress(&self) -> Option<ProgressContext>;
fn progress_guard(&self) -> Option<ProgressGuard>;
#[doc(hidden)]
fn _set_progress(&self, ctx: Option<ProgressContext>);
fn has_progress(&self) -> bool;
}
impl TaskProgressExt for super::Task {
fn progress(&self) -> Option<ProgressContext> {
PROGRESS_CONTEXT.with(|cell| {
cell.borrow().as_ref().and_then(|ctx| {
if ctx.task_id() == self.id {
Some(ctx.clone())
} else {
None
}
})
})
}
fn progress_guard(&self) -> Option<ProgressGuard> {
PROGRESS_CONTEXT.with(|cell| {
cell.borrow().as_ref().and_then(|ctx| {
if ctx.task_id() == self.id {
Some(ProgressGuard)
} else {
None
}
})
})
}
fn _set_progress(&self, ctx: Option<ProgressContext>) {
PROGRESS_CONTEXT.with(|cell| {
*cell.borrow_mut() = ctx;
});
}
fn has_progress(&self) -> bool {
PROGRESS_CONTEXT.with(|cell| {
cell.borrow().is_some()
})
}
}
pub fn set_progress_context(ctx: Option<ProgressContext>) {
PROGRESS_CONTEXT.with(|cell| {
*cell.borrow_mut() = ctx;
});
}
pub fn get_progress_context() -> Option<ProgressContext> {
PROGRESS_CONTEXT.with(|cell| {
cell.borrow().clone()
})
}
pub fn clear_progress_context() {
set_progress_context(None);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_progress_context_none_initially() {
assert!(get_progress_context().is_none());
}
#[test]
fn test_set_get_progress_context() {
assert!(get_progress_context().is_none());
}
}