Skip to main content

rust_expect/dialog/
common.rs

1//! Common dialog patterns.
2
3use std::time::Duration;
4
5use super::definition::{Dialog, DialogBuilder, DialogStep};
6
7/// Create a login dialog.
8#[must_use]
9pub fn login_dialog(username: &str, password: &str) -> Dialog {
10    DialogBuilder::named("login")
11        .expect_send("username", "login:", format!("{username}\n"))
12        .expect_send("password", "assword:", format!("{password}\n"))
13        .build()
14}
15
16/// Create an SSH dialog with host key acceptance.
17#[must_use]
18pub fn ssh_dialog(host: &str, username: &str, password: &str) -> Dialog {
19    Dialog::named("ssh")
20        .variable("HOST", host)
21        .variable("USER", username)
22        .variable("PASS", password)
23        .step(
24            DialogStep::new("hostkey")
25                .with_expect("(yes/no")
26                .with_send("yes\n")
27                .then("password"),
28        )
29        .step(
30            DialogStep::new("password")
31                .with_expect("assword:")
32                .with_send("${PASS}\n"),
33        )
34}
35
36/// Create a sudo dialog.
37#[must_use]
38pub fn sudo_dialog(password: &str) -> Dialog {
39    DialogBuilder::named("sudo")
40        .expect_send("password", "[sudo] password", format!("{password}\n"))
41        .build()
42}
43
44/// Create a yes/no confirmation dialog.
45#[must_use]
46pub fn confirm_dialog(answer: bool) -> Dialog {
47    let response = if answer { "yes\n" } else { "no\n" };
48    DialogBuilder::named("confirm")
49        .expect_send("confirm", "[y/n]", response)
50        .build()
51}
52
53/// Create a menu selection dialog.
54#[must_use]
55pub fn menu_dialog(selection: &str) -> Dialog {
56    DialogBuilder::named("menu")
57        .expect_send("select", "choice:", format!("{selection}\n"))
58        .build()
59}
60
61/// Create a FTP login dialog.
62#[must_use]
63pub fn ftp_dialog(username: &str, password: &str) -> Dialog {
64    Dialog::named("ftp")
65        .step(
66            DialogStep::new("user")
67                .with_expect("Name")
68                .with_send(format!("{username}\n")),
69        )
70        .step(
71            DialogStep::new("pass")
72                .with_expect("Password")
73                .with_send(format!("{password}\n")),
74        )
75}
76
77/// Create a telnet login dialog.
78#[must_use]
79pub fn telnet_dialog(username: &str, password: &str) -> Dialog {
80    Dialog::named("telnet")
81        .step(
82            DialogStep::new("login")
83                .with_expect("login:")
84                .with_send(format!("{username}\n")),
85        )
86        .step(
87            DialogStep::new("password")
88                .with_expect("Password:")
89                .with_send(format!("{password}\n")),
90        )
91}
92
93/// Create a git credential dialog.
94#[must_use]
95pub fn git_credential_dialog(username: &str, password: &str) -> Dialog {
96    Dialog::named("git")
97        .step(
98            DialogStep::new("user")
99                .with_expect("Username")
100                .with_send(format!("{username}\n")),
101        )
102        .step(
103            DialogStep::new("pass")
104                .with_expect("Password")
105                .with_send(format!("{password}\n")),
106        )
107}
108
109/// Create a prompt continuation dialog.
110#[must_use]
111pub fn shell_prompt_dialog(prompt: &str) -> Dialog {
112    Dialog::named("shell").step(
113        DialogStep::new("prompt")
114            .with_expect(prompt)
115            .timeout(Duration::from_secs(5)),
116    )
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn login_dialog_creation() {
125        let dialog = login_dialog("user", "pass");
126        assert_eq!(dialog.name, "login");
127        assert_eq!(dialog.steps.len(), 2);
128    }
129
130    #[test]
131    fn ssh_dialog_has_variables() {
132        let dialog = ssh_dialog("host", "user", "pass");
133        assert_eq!(dialog.variables.get("HOST"), Some(&"host".to_string()));
134    }
135}