agent_tui_usecases/usecases/
wait.rs1use std::sync::Arc;
4use std::time::Duration;
5
6use crate::domain::WaitInput;
7use crate::domain::WaitOutput;
8use crate::usecases::ports::Clock;
9use crate::usecases::ports::SessionError;
10use crate::usecases::ports::SessionRepository;
11use crate::usecases::wait_condition::StableTracker;
12use crate::usecases::wait_condition::WaitCondition;
13use crate::usecases::wait_condition::check_condition;
14
15pub trait WaitUseCase: Send + Sync {
16 fn execute(&self, input: WaitInput) -> Result<WaitOutput, SessionError>;
17}
18
19pub struct WaitUseCaseImpl<R: SessionRepository> {
20 repository: Arc<R>,
21 clock: Arc<dyn Clock>,
22}
23
24impl<R: SessionRepository> WaitUseCaseImpl<R> {
25 pub fn new(repository: Arc<R>, clock: Arc<dyn Clock>) -> Self {
26 Self { repository, clock }
27 }
28}
29
30impl<R: SessionRepository> WaitUseCase for WaitUseCaseImpl<R> {
31 fn execute(&self, input: WaitInput) -> Result<WaitOutput, SessionError> {
32 let session = self.repository.resolve(input.session_id.as_ref())?;
33 let timeout = Duration::from_millis(input.timeout_ms);
34 let start = self.clock.now();
35
36 let condition = WaitCondition::parse(input.condition, input.text.as_deref())
37 .map_err(|e| SessionError::InvalidKey(e.to_string()))?;
38
39 let mut stable_tracker = StableTracker::new(3);
40 let poll_interval = Duration::from_millis(50);
41 let subscription = session.stream_subscribe();
42
43 loop {
44 session.update()?;
45
46 if check_condition(session.as_ref(), &condition, &mut stable_tracker) {
47 let elapsed_ms = self.clock.elapsed_ms(start);
48 return Ok(WaitOutput {
49 found: true,
50 elapsed_ms,
51 });
52 }
53
54 if self.clock.elapsed(start) >= timeout {
55 let elapsed_ms = self.clock.elapsed_ms(start);
56 return Ok(WaitOutput {
57 found: false,
58 elapsed_ms,
59 });
60 }
61
62 let remaining = timeout.saturating_sub(self.clock.elapsed(start));
63 let wait_timeout = remaining.min(poll_interval);
64 let _ = subscription.wait(Some(wait_timeout));
65 }
66 }
67}
68
69#[cfg(test)]
70#[path = "wait_tests.rs"]
71mod tests;