1use std::time::Duration;
28
29use inquire::error::InquireResult;
30use inquire::validator::Validation;
31use inquire::Text;
32
33use crate::actions::h3::Action;
34use crate::actions::h3::StreamEvent;
35use crate::actions::h3::StreamEventType;
36use crate::actions::h3::WaitType;
37
38use super::prompt_stream_id;
39use super::squish_suggester;
40use super::validate_wait_period;
41use super::SuggestionResult;
42
43const DURATION: &str = "duration";
44const HEADERS: &str = "headers";
45const DATA: &str = "data";
46const FINISHED: &str = "stream finished";
47
48pub fn prompt_wait() -> InquireResult<Action> {
49 let wait_type = Text::new("wait type:")
50 .with_autocomplete(&wait_type_suggestor)
51 .with_validator(wait_type_validator)
52 .prompt()?;
53
54 let actual = match wait_type.as_str() {
55 DURATION => Some(prompt_wait_period()),
56 t @ (HEADERS | DATA | FINISHED) => Some(prompt_stream_wait(t)),
57 _ => None,
58 };
59
60 let action = Action::Wait {
61 wait_type: actual.unwrap()?,
63 };
64
65 Ok(action)
66}
67
68fn wait_type_suggestor(val: &str) -> SuggestionResult<Vec<String>> {
69 let suggestions = [DURATION, HEADERS, DATA, FINISHED];
70
71 squish_suggester(&suggestions, val)
72}
73
74fn wait_type_validator(wait_type: &str) -> SuggestionResult<Validation> {
75 match wait_type {
76 DURATION | HEADERS | DATA | FINISHED => Ok(Validation::Valid),
77 _ => Ok(Validation::Invalid(
78 inquire::validator::ErrorMessage::Default,
79 )),
80 }
81}
82
83fn prompt_stream_wait(stream_wait_type: &str) -> InquireResult<WaitType> {
84 let stream_id = prompt_stream_id()?;
85
86 let event_type = if let HEADERS = stream_wait_type {
87 Some(StreamEventType::Headers)
88 } else if let DATA = stream_wait_type {
89 Some(StreamEventType::Data)
90 } else if let FINISHED = stream_wait_type {
91 Some(StreamEventType::Finished)
92 } else {
93 None
94 }
95 .unwrap();
98
99 Ok(WaitType::StreamEvent(StreamEvent {
100 stream_id,
101 event_type,
102 }))
103}
104
105pub fn prompt_wait_period() -> InquireResult<WaitType> {
106 let period = Text::new("wait period (ms):")
107 .with_validator(validate_wait_period)
108 .prompt()?;
109
110 let period = Duration::from_millis(period.parse::<u64>().unwrap());
112
113 Ok(WaitType::WaitDuration(period))
114}