use std::time::Duration;
use rust_expect::dialog::{DialogBuilder, DialogStep};
use rust_expect::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
println!("rust-expect Dialog Automation Example");
println!("======================================\n");
println!("1. Simple login dialog definition...");
let dialog = DialogBuilder::new()
.step(DialogStep::expect("Username:").then_send("testuser\n"))
.step(DialogStep::expect("Password:").then_send("testpass\n"))
.step(DialogStep::expect(r"[#$>]"))
.build();
println!(" Dialog built with {} steps", dialog.len());
for (i, step) in dialog.steps().iter().enumerate() {
println!(
" Step {}: expect '{:?}' -> send '{:?}'",
i + 1,
step.expect_pattern(),
step.send_text()
);
}
println!("\n2. Dialog with variable substitution...");
let username = "admin";
let password = "secret123";
let dialog = DialogBuilder::new()
.var("user", username)
.var("pass", password)
.step(DialogStep::expect("login:").then_send("${user}\n"))
.step(DialogStep::expect("password:").then_send("${pass}\n"))
.build();
println!(" Variables defined: user={username}, pass=****");
println!(
" Variable substitution test: '{}'",
dialog.substitute("Hello ${user}")
);
println!("\n3. Named dialog with chained steps...");
let dialog = DialogBuilder::named("ssh-login")
.step(
DialogStep::new("username")
.with_expect("login:")
.with_send("myuser\n"),
)
.step(
DialogStep::new("password")
.with_expect("password:")
.with_send("mypass\n")
.timeout(Duration::from_secs(30)),
)
.step(DialogStep::new("prompt").with_expect(r"[$#>]"))
.build();
println!(" Dialog '{}' with {} steps", dialog.name, dialog.len());
println!("\n4. Dialog with control characters...");
let ctrl_c = ControlChar::CtrlC; let ctrl_m = ControlChar::CtrlM; let ctrl_d = ControlChar::CtrlD;
println!(" Control characters:");
println!(" - Ctrl+C (interrupt): 0x{:02x}", ctrl_c.as_byte());
println!(" - Ctrl+M (enter): 0x{:02x}", ctrl_m.as_byte());
println!(" - Ctrl+D (EOF): 0x{:02x}", ctrl_d.as_byte());
let _dialog = DialogBuilder::new()
.step(DialogStep::expect("Continue? [y/n]").then_send("y"))
.step(DialogStep::expect("Press Enter").then_send("\n"))
.build();
println!(" Dialog ready for interactive prompts");
println!("\n5. Using expect_send shorthand...");
let dialog = DialogBuilder::new()
.expect_send("step1", "First prompt:", "response1\n")
.expect_send("step2", "Second prompt:", "response2\n")
.expect_send("done", r"[$#>]", "")
.build();
println!(" Created {} steps with expect_send()", dialog.len());
println!("\n6. Executing a real dialog...");
let mut session = Session::spawn("/bin/sh", &[]).await?;
session
.expect_timeout(Pattern::shell_prompt(), Duration::from_secs(2))
.await?;
session
.send_line("read -p 'Enter name: ' name && echo \"Hello, $name!\"")
.await?;
session.expect("Enter name:").await?;
println!(" Saw prompt: 'Enter name:'");
session.send_line("World").await?;
println!(" Sent: 'World'");
let m = session.expect("Hello, World").await?;
println!(" Received: '{}'", m.matched.trim());
println!("\n7. Step timeout configuration...");
let step_with_timeout = DialogStep::new("wait_for_slow")
.with_expect("Slow operation complete")
.with_send("next\n")
.timeout(Duration::from_secs(120))
.continue_on_timeout(true);
println!(" Step timeout: {:?}", step_with_timeout.get_timeout());
println!(
" Continue on timeout: {}",
step_with_timeout.continues_on_timeout()
);
session.send_line("exit").await?;
session.wait().await?;
println!("\nDialog examples completed successfully!");
Ok(())
}