Skip to main content

aurora_modules/
timer.rs

1use aurora_core::{AuroraResult, Pipeline, Value};
2use std::sync::Mutex;
3use std::time::{Duration, Instant};
4
5#[derive(Clone)]
6struct TimerEntry {
7    name: String,
8    total_secs: u64,
9    started: Instant,
10}
11
12static TIMERS: Mutex<Option<Vec<TimerEntry>>> = Mutex::new(None);
13
14fn get_timers() -> Vec<TimerEntry> {
15    let guard = TIMERS.lock().unwrap_or_else(|e| e.into_inner());
16    guard.clone().unwrap_or_default()
17}
18
19fn set_timers(timers: Vec<TimerEntry>) {
20    let mut guard = TIMERS.lock().unwrap_or_else(|e| e.into_inner());
21    *guard = Some(timers);
22}
23
24pub fn timer_start(seconds: u64, name: Option<&str>) -> AuroraResult<Pipeline> {
25    let name = name.unwrap_or("timer").to_string();
26    let entry = TimerEntry {
27        name: name.clone(),
28        total_secs: seconds,
29        started: Instant::now(),
30    };
31
32    let mut timers = get_timers();
33    timers.push(entry);
34    set_timers(timers);
35
36    let name_clone = name.clone();
37    std::thread::spawn(move || {
38        std::thread::sleep(Duration::from_secs(seconds));
39        let _ = std::io::Write::write_all(
40            &mut std::io::stdout(),
41            format!("\x07\x1b[1;32m=== Timer '{}' finished! ===\x1b[0m\n", name_clone).as_bytes(),
42        );
43    });
44
45    Ok(Pipeline::table(
46        vec!["name".into(), "seconds".into(), "status".into()],
47        vec![vec![
48            Value::String(name),
49            Value::Int(seconds as i64),
50            Value::String("started".into()),
51        ]],
52    ))
53}
54
55pub fn timer_stop() -> AuroraResult<Pipeline> {
56    let timers = get_timers();
57    let count = timers.len();
58    set_timers(Vec::new());
59
60    Ok(Pipeline::table(
61        vec!["action".into(), "stopped".into()],
62        vec![vec![
63            Value::String("stop".into()),
64            Value::Int(count as i64),
65        ]],
66    ))
67}
68
69pub fn timer_status() -> AuroraResult<Pipeline> {
70    let timers = get_timers();
71    let mut rows: Vec<Vec<Value>> = Vec::new();
72
73    for timer in &timers {
74        let elapsed = timer.started.elapsed().as_secs();
75        let remaining = if elapsed >= timer.total_secs {
76            0
77        } else {
78            timer.total_secs - elapsed
79        };
80
81        rows.push(vec![
82            Value::String(timer.name.clone()),
83            Value::Int(remaining as i64),
84            Value::Int(timer.total_secs as i64),
85        ]);
86    }
87
88    Ok(Pipeline::table(
89        vec!["name".into(), "remaining".into(), "total".into()],
90        rows,
91    ))
92}