phosphor_app/state/
input.rs1use std::time::Instant;
4
5#[derive(Debug)]
6pub struct NumberBuffer {
7 digits: String,
8 last_input: Option<Instant>,
9 timeout_ms: u128,
10}
11
12impl Default for NumberBuffer {
13 fn default() -> Self { Self::new() }
14}
15
16impl NumberBuffer {
17 pub fn new() -> Self { Self { digits: String::new(), last_input: None, timeout_ms: 500 } }
18
19 pub fn push_digit(&mut self, ch: char) -> Option<usize> {
20 if self.is_timed_out() { self.digits.clear(); }
21 self.digits.push(ch);
22 self.last_input = Some(Instant::now());
23 None
24 }
25
26 pub fn check_timeout(&mut self) -> Option<usize> {
27 if self.digits.is_empty() { return None; }
28 if self.is_timed_out() {
29 let num = self.digits.parse::<usize>().ok();
30 self.digits.clear();
31 self.last_input = None;
32 num
33 } else { None }
34 }
35
36 fn is_timed_out(&self) -> bool {
37 self.last_input.map(|t| t.elapsed().as_millis() >= self.timeout_ms).unwrap_or(true)
38 }
39
40 pub fn display(&self) -> &str {
41 if self.is_timed_out() { "" } else { &self.digits }
42 }
43
44 pub fn commit(&mut self) -> Option<usize> {
45 if self.digits.is_empty() { return None; }
46 let num = self.digits.parse::<usize>().ok();
47 self.digits.clear();
48 self.last_input = None;
49 num
50 }
51}