use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiagnosticsStrategy {
Version,
TokenMonitor,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ActivityState {
Active,
Idle,
Dead,
}
pub trait ProgressMonitor {
fn poll(&mut self) -> ActivityState;
}
pub struct TokenMonitor {
state: Arc<std::sync::atomic::AtomicU8>,
alive: Arc<std::sync::atomic::AtomicBool>,
}
impl TokenMonitor {
pub const fn new(
state: Arc<std::sync::atomic::AtomicU8>,
alive: Arc<std::sync::atomic::AtomicBool>,
) -> Self {
Self { state, alive }
}
}
impl ProgressMonitor for TokenMonitor {
fn poll(&mut self) -> ActivityState {
use std::sync::atomic::Ordering;
if !self.alive.load(Ordering::SeqCst) {
return ActivityState::Dead;
}
let state = crate::lsp::state::ServerState::from_u8(self.state.load(Ordering::SeqCst));
match state {
crate::lsp::state::ServerState::Busy => ActivityState::Active,
crate::lsp::state::ServerState::Dead => ActivityState::Dead,
_ => ActivityState::Idle,
}
}
}
#[cfg(test)]
#[allow(
clippy::expect_used,
reason = "tests use expect for readable assertions"
)]
mod tests {
use super::*;
use std::sync::atomic::{AtomicBool, AtomicU8};
#[test]
fn token_monitor_idle_when_ready() {
let state = Arc::new(AtomicU8::new(crate::lsp::state::ServerState::Ready.as_u8()));
let alive = Arc::new(AtomicBool::new(true));
let mut monitor = TokenMonitor::new(state, alive);
assert_eq!(monitor.poll(), ActivityState::Idle);
}
#[test]
fn token_monitor_active_when_busy() {
let state = Arc::new(AtomicU8::new(crate::lsp::state::ServerState::Busy.as_u8()));
let alive = Arc::new(AtomicBool::new(true));
let mut monitor = TokenMonitor::new(state, alive);
assert_eq!(monitor.poll(), ActivityState::Active);
}
#[test]
fn token_monitor_idle_when_stuck() {
let state = Arc::new(AtomicU8::new(crate::lsp::state::ServerState::Stuck.as_u8()));
let alive = Arc::new(AtomicBool::new(true));
let mut monitor = TokenMonitor::new(state, alive);
assert_eq!(monitor.poll(), ActivityState::Idle);
}
#[test]
fn token_monitor_dead_when_not_alive() {
let state = Arc::new(AtomicU8::new(crate::lsp::state::ServerState::Ready.as_u8()));
let alive = Arc::new(AtomicBool::new(false));
let mut monitor = TokenMonitor::new(state, alive);
assert_eq!(monitor.poll(), ActivityState::Dead);
}
}