use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct Ton {
pub en: bool,
pub pt: Duration,
pub q: bool,
pub et: Duration,
start_time: Option<Instant>,
active: bool,
}
impl Ton {
pub fn new() -> Self {
Self {
en: false,
pt: Duration::default(),
q: false,
et: Duration::default(),
start_time: None,
active: false,
}
}
pub fn call(&mut self, en: bool, pt: Duration) -> bool {
self.en = en;
self.pt = pt;
if !self.en {
self.q = false;
self.et = Duration::ZERO;
self.start_time = None;
self.active = false;
} else {
if !self.active {
self.start_time = Some(Instant::now());
self.active = true;
self.et = Duration::ZERO;
self.q = false;
} else {
if let Some(start) = self.start_time {
self.et = start.elapsed();
if self.et >= self.pt {
self.et = self.pt; self.q = true;
}
}
}
}
self.q
}
pub fn reset(&mut self) {
self.q = false;
self.et = Duration::ZERO;
self.start_time = None;
self.active = false;
}
}
impl Default for Ton {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ton_basic() {
let mut timer = Ton::new();
let pt = Duration::from_millis(50);
assert_eq!(timer.call(false, pt), false);
assert_eq!(timer.et, Duration::ZERO);
assert_eq!(timer.call(true, pt), false);
assert!(timer.et < pt);
std::thread::sleep(Duration::from_millis(60));
assert_eq!(timer.call(true, pt), true);
assert_eq!(timer.et, pt);
timer.reset();
assert_eq!(timer.q, false);
assert_eq!(timer.et, Duration::ZERO);
}
}