interact_with_callback/
interact_with_callback.rs

1use expectrl::{
2    interact::{actions::lookup::Lookup, InteractOptions},
3    spawn,
4    stream::stdin::Stdin,
5    Regex,
6};
7
8#[derive(Debug, Default)]
9struct State {
10    stutus_verification_counter: Option<usize>,
11    wait_for_continue: Option<bool>,
12    pressed_yes_on_continue: Option<bool>,
13}
14
15#[cfg(not(all(windows, feature = "polling")))]
16#[cfg(not(feature = "async"))]
17fn main() {
18    let mut output_action = Lookup::new();
19    let mut input_action = Lookup::new();
20    let mut state = State::default();
21    let opts = InteractOptions::new(&mut state)
22        .on_output(|mut ctx| {
23            let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?;
24            if m.is_some() {
25                ctx.state.wait_for_continue = Some(true);
26            };
27
28            let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?;
29            if m.is_some() {
30                ctx.state.stutus_verification_counter =
31                    Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1));
32                output_action.clear();
33            }
34
35            Ok(false)
36        })
37        .on_input(|mut ctx| {
38            let m = input_action.on(ctx.buf, ctx.eof, "y")?;
39            if m.is_some() {
40                if let Some(_a @ true) = ctx.state.wait_for_continue {
41                    ctx.state.pressed_yes_on_continue = Some(true);
42                }
43            };
44
45            let m = input_action.on(ctx.buf, ctx.eof, "n")?;
46            if m.is_some() {
47                if let Some(_a @ true) = ctx.state.wait_for_continue {
48                    ctx.state.pressed_yes_on_continue = Some(false);
49                }
50            }
51
52            Ok(false)
53        });
54
55    let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");
56
57    let mut stdin = Stdin::open().unwrap();
58    let stdout = std::io::stdout();
59
60    let mut interact = session.interact(&mut stdin, stdout);
61
62    let is_alive = interact.spawn(opts).expect("Failed to start interact");
63
64    if !is_alive {
65        println!("The process was exited");
66        #[cfg(unix)]
67        println!("Status={:?}", interact.get_status());
68    }
69
70    stdin.close().unwrap();
71
72    println!("RESULTS");
73    println!(
74        "Number of time 'Y' was pressed = {}",
75        state.pressed_yes_on_continue.unwrap_or_default()
76    );
77    println!(
78        "Status counter = {}",
79        state.stutus_verification_counter.unwrap_or_default()
80    );
81}
82
83#[cfg(feature = "async")]
84fn main() {
85    let mut output_action = Lookup::new();
86    let mut input_action = Lookup::new();
87    let mut state = State::default();
88    let opts = InteractOptions::new(&mut state)
89        .on_output(|mut ctx| {
90            let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?;
91            if m.is_some() {
92                ctx.state.wait_for_continue = Some(true);
93            };
94
95            let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?;
96            if m.is_some() {
97                ctx.state.stutus_verification_counter =
98                    Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1));
99                output_action.clear();
100            }
101
102            Ok(false)
103        })
104        .on_input(|mut ctx| {
105            let m = input_action.on(ctx.buf, ctx.eof, "y")?;
106            if m.is_some() {
107                if let Some(_a @ true) = ctx.state.wait_for_continue {
108                    ctx.state.pressed_yes_on_continue = Some(true);
109                }
110            };
111
112            let m = input_action.on(ctx.buf, ctx.eof, "n")?;
113            if m.is_some() {
114                if let Some(_a @ true) = ctx.state.wait_for_continue {
115                    ctx.state.pressed_yes_on_continue = Some(false);
116                }
117            }
118
119            Ok(false)
120        });
121
122    let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");
123
124    let mut stdin = Stdin::open().unwrap();
125    let stdout = std::io::stdout();
126
127    let mut interact = session.interact(&mut stdin, stdout);
128
129    let is_alive =
130        futures_lite::future::block_on(interact.spawn(opts)).expect("Failed to start interact");
131
132    if !is_alive {
133        println!("The process was exited");
134        #[cfg(unix)]
135        println!("Status={:?}", interact.get_status());
136    }
137
138    stdin.close().unwrap();
139
140    println!("RESULTS");
141    println!(
142        "Number of time 'Y' was pressed = {}",
143        state.pressed_yes_on_continue.unwrap_or_default()
144    );
145    println!(
146        "Status counter = {}",
147        state.stutus_verification_counter.unwrap_or_default()
148    );
149}
150
151#[cfg(all(windows, feature = "polling", not(feature = "async")))]
152fn main() {}