use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use crate::cli::ThreadMode;
use crate::error::{CliError, Result};
pub const EXIT_CODE_INTERRUPTED: i32 = 130;
static INTERRUPTED: AtomicBool = AtomicBool::new(false);
pub fn is_interrupted() -> bool {
INTERRUPTED.load(Ordering::SeqCst)
}
pub fn setup_signal_handler() -> Result<Arc<AtomicBool>> {
let flag = Arc::new(AtomicBool::new(false));
let flag_clone = Arc::clone(&flag);
ctrlc::set_handler(move || {
INTERRUPTED.store(true, Ordering::SeqCst);
flag_clone.store(true, Ordering::SeqCst);
eprintln!("\nInterrupted. Cleaning up...");
})
.map_err(|e| CliError::Io(std::io::Error::other(e)))?;
Ok(flag)
}
pub fn validate_thread_mode(mode: ThreadMode, quiet: bool) -> ThreadMode {
match mode {
ThreadMode::Multi => ThreadMode::Multi,
ThreadMode::Single => {
if !quiet {
eprintln!(
"Warning: Single-threaded mode (--thread-mode single) is not supported in v0.3.2."
);
eprintln!(" Falling back to multi-threaded mode. (v0.4+ で有効化予定)");
}
ThreadMode::Multi
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_thread_mode_multi() {
let result = validate_thread_mode(ThreadMode::Multi, false);
assert_eq!(result, ThreadMode::Multi);
}
#[test]
fn test_validate_thread_mode_single_quiet() {
let result = validate_thread_mode(ThreadMode::Single, true);
assert_eq!(result, ThreadMode::Multi);
}
#[test]
fn test_validate_thread_mode_single_verbose() {
let result = validate_thread_mode(ThreadMode::Single, false);
assert_eq!(result, ThreadMode::Multi);
}
#[test]
fn test_is_interrupted_default() {
assert!(!is_interrupted() || is_interrupted()); }
#[test]
fn test_exit_code_interrupted() {
assert_eq!(EXIT_CODE_INTERRUPTED, 130);
}
}