use std::cell::Cell;
pub enum Propagate {
AsIs,
Replace(Vec<Vec<u8>>),
Suppress,
}
thread_local! {
static OVERRIDE: Cell<Option<Propagate>> = const { Cell::new(None) };
}
pub fn set_override(p: Propagate) {
OVERRIDE.with(|c| c.set(Some(p)));
}
pub(crate) fn take_override() -> Propagate {
OVERRIDE.with(Cell::take).unwrap_or(Propagate::AsIs)
}
pub fn discard_override() {
OVERRIDE.with(Cell::take);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_is_as_is() {
assert!(matches!(take_override(), Propagate::AsIs));
}
#[test]
fn take_consumes_the_override() {
set_override(Propagate::Replace(vec![b"SREM".to_vec(), b"k".to_vec()]));
let Propagate::Replace(frame) = take_override() else {
panic!("expected Replace");
};
assert_eq!(frame.len(), 2);
assert!(matches!(take_override(), Propagate::AsIs));
}
#[test]
fn discard_drops_without_recording() {
set_override(Propagate::Suppress);
discard_override();
assert!(matches!(take_override(), Propagate::AsIs));
}
#[test]
fn last_set_wins() {
set_override(Propagate::Suppress);
set_override(Propagate::Replace(vec![b"SREM".to_vec()]));
assert!(matches!(take_override(), Propagate::Replace(_)));
}
}
use core::cell::RefCell;
thread_local! {
static TICK_FRAMES: RefCell<Vec<Vec<Vec<u8>>>> = const { RefCell::new(Vec::new()) };
}
pub fn push_tick_frame(argv: Vec<Vec<u8>>) {
TICK_FRAMES.with(|q| q.borrow_mut().push(argv));
}
pub(crate) fn take_tick_frames() -> Vec<Vec<Vec<u8>>> {
TICK_FRAMES.with(|q| core::mem::take(&mut *q.borrow_mut()))
}