pub struct InteractOptions<C, IF, OF, IA, OA, WA> { /* private fields */ }
Expand description

Interact options (aka callbacks you can set to be callled being in an interactive mode).

Implementations§

source§

impl<S, I, O, C> InteractOptions<C, NoFilter, NoFilter, NoAction<Session<OsProcess, S>, I, O, C>, NoAction<Session<OsProcess, S>, I, O, C>, NoAction<Session<OsProcess, S>, I, O, C>>

source

pub fn new(state: C) -> Self

Set a state.

Examples found in repository?
examples/ftp_interact.rs (line 14)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
fn main() -> Result<(), Error> {
    let mut auth = false;
    let mut login_lookup = Lookup::new();
    let opts = InteractOptions::new(&mut auth).on_output(|ctx| {
        if login_lookup
            .on(ctx.buf, ctx.eof, "Login successful")?
            .is_some()
        {
            **ctx.state = true;
            return Ok(true);
        }

        Ok(false)
    });

    let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?;

    let mut stdin = Stdin::open()?;
    p.interact(&mut stdin, stdout()).spawn(opts)?;
    stdin.close()?;

    if !auth {
        println!("An authefication was not passed");
        return Ok(());
    }

    p.expect("ftp>")?;
    p.send_line("cd upload")?;
    p.expect("successfully changed.")?;
    p.send_line("pwd")?;
    p.expect(Regex("[0-9]+ \"/upload\""))?;
    p.send(ControlCode::EndOfTransmission)?;
    p.expect("Goodbye.")?;
    Ok(())
}
More examples
Hide additional examples
examples/interact_with_callback.rs (line 21)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
fn main() {
    let mut output_action = Lookup::new();
    let mut input_action = Lookup::new();
    let mut state = State::default();
    let opts = InteractOptions::new(&mut state)
        .on_output(|mut ctx| {
            let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?;
            if m.is_some() {
                ctx.state.wait_for_continue = Some(true);
            };

            let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?;
            if m.is_some() {
                ctx.state.stutus_verification_counter =
                    Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1));
                output_action.clear();
            }

            Ok(false)
        })
        .on_input(|mut ctx| {
            let m = input_action.on(ctx.buf, ctx.eof, "y")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(true);
                }
            };

            let m = input_action.on(ctx.buf, ctx.eof, "n")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(false);
                }
            }

            Ok(false)
        });

    let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");

    let mut stdin = Stdin::open().unwrap();
    let stdout = std::io::stdout();

    let mut interact = session.interact(&mut stdin, stdout);

    let is_alive = interact.spawn(opts).expect("Failed to start interact");

    if !is_alive {
        println!("The process was exited");
        #[cfg(unix)]
        println!("Status={:?}", interact.get_status());
    }

    stdin.close().unwrap();

    println!("RESULTS");
    println!(
        "Number of time 'Y' was pressed = {}",
        state.pressed_yes_on_continue.unwrap_or_default()
    );
    println!(
        "Status counter = {}",
        state.stutus_verification_counter.unwrap_or_default()
    );
}
source§

impl<C, IF, OF, IA, OA, WA> InteractOptions<C, IF, OF, IA, OA, WA>

source

pub fn get_state(&self) -> &C

Get a reference on state

source

pub fn get_state_mut(&mut self) -> &mut C

Get a mut reference on state

source

pub fn into_inner(self) -> C

Returns a inner state.

source

pub fn output_filter<F>( self, filter: F ) -> InteractOptions<C, IF, F, IA, OA, WA>where F: FnMut(&[u8]) -> Result<Cow<'_, [u8]>, Error>,

Sets the output filter. The output_filter will be passed all the output from the child process.

The filter isn’t applied to user’s read calls through the Context in callbacks.

source

pub fn input_filter<F>(self, filter: F) -> InteractOptions<C, F, OF, IA, OA, WA>where F: FnMut(&[u8]) -> Result<Cow<'_, [u8]>, Error>,

Sets the input filter. The input_filter will be passed all the keyboard input from the user.

The input_filter is run BEFORE the check for the escape_character. The filter is called BEFORE calling a on_input callback if it’s set.

source§

impl<S, I, O, C, IF, OF, OA, WA> InteractOptions<C, IF, OF, NoAction<Session<OsProcess, S>, I, O, C>, OA, WA>

source

pub fn on_input<F>(self, action: F) -> InteractOptions<C, IF, OF, F, OA, WA>where F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool, Error>,

Puts a hanlder which will be called when users input is detected.

Be aware that currently async version doesn’t take a Session as an argument. See https://github.com/zhiburt/expectrl/issues/16.

Examples found in repository?
examples/interact_with_callback.rs (lines 37-53)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
fn main() {
    let mut output_action = Lookup::new();
    let mut input_action = Lookup::new();
    let mut state = State::default();
    let opts = InteractOptions::new(&mut state)
        .on_output(|mut ctx| {
            let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?;
            if m.is_some() {
                ctx.state.wait_for_continue = Some(true);
            };

            let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?;
            if m.is_some() {
                ctx.state.stutus_verification_counter =
                    Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1));
                output_action.clear();
            }

            Ok(false)
        })
        .on_input(|mut ctx| {
            let m = input_action.on(ctx.buf, ctx.eof, "y")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(true);
                }
            };

            let m = input_action.on(ctx.buf, ctx.eof, "n")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(false);
                }
            }

            Ok(false)
        });

    let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");

    let mut stdin = Stdin::open().unwrap();
    let stdout = std::io::stdout();

    let mut interact = session.interact(&mut stdin, stdout);

    let is_alive = interact.spawn(opts).expect("Failed to start interact");

    if !is_alive {
        println!("The process was exited");
        #[cfg(unix)]
        println!("Status={:?}", interact.get_status());
    }

    stdin.close().unwrap();

    println!("RESULTS");
    println!(
        "Number of time 'Y' was pressed = {}",
        state.pressed_yes_on_continue.unwrap_or_default()
    );
    println!(
        "Status counter = {}",
        state.stutus_verification_counter.unwrap_or_default()
    );
}
source§

impl<S, I, O, C, IF, OF, IA, WA> InteractOptions<C, IF, OF, IA, NoAction<Session<OsProcess, S>, I, O, C>, WA>

source

pub fn on_output<F>(self, action: F) -> InteractOptions<C, IF, OF, IA, F, WA>where F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool, Error>,

Puts a hanlder which will be called when process output is detected.

IMPORTANT:

Please be aware that your use of Session::expect, Session::check and any read operation on session will cause the read bytes not to apeard in the output stream!

Examples found in repository?
examples/ftp_interact.rs (lines 14-24)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
fn main() -> Result<(), Error> {
    let mut auth = false;
    let mut login_lookup = Lookup::new();
    let opts = InteractOptions::new(&mut auth).on_output(|ctx| {
        if login_lookup
            .on(ctx.buf, ctx.eof, "Login successful")?
            .is_some()
        {
            **ctx.state = true;
            return Ok(true);
        }

        Ok(false)
    });

    let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?;

    let mut stdin = Stdin::open()?;
    p.interact(&mut stdin, stdout()).spawn(opts)?;
    stdin.close()?;

    if !auth {
        println!("An authefication was not passed");
        return Ok(());
    }

    p.expect("ftp>")?;
    p.send_line("cd upload")?;
    p.expect("successfully changed.")?;
    p.send_line("pwd")?;
    p.expect(Regex("[0-9]+ \"/upload\""))?;
    p.send(ControlCode::EndOfTransmission)?;
    p.expect("Goodbye.")?;
    Ok(())
}
More examples
Hide additional examples
examples/interact_with_callback.rs (lines 22-36)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
fn main() {
    let mut output_action = Lookup::new();
    let mut input_action = Lookup::new();
    let mut state = State::default();
    let opts = InteractOptions::new(&mut state)
        .on_output(|mut ctx| {
            let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?;
            if m.is_some() {
                ctx.state.wait_for_continue = Some(true);
            };

            let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?;
            if m.is_some() {
                ctx.state.stutus_verification_counter =
                    Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1));
                output_action.clear();
            }

            Ok(false)
        })
        .on_input(|mut ctx| {
            let m = input_action.on(ctx.buf, ctx.eof, "y")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(true);
                }
            };

            let m = input_action.on(ctx.buf, ctx.eof, "n")?;
            if m.is_some() {
                if let Some(_a @ true) = ctx.state.wait_for_continue {
                    ctx.state.pressed_yes_on_continue = Some(false);
                }
            }

            Ok(false)
        });

    let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");

    let mut stdin = Stdin::open().unwrap();
    let stdout = std::io::stdout();

    let mut interact = session.interact(&mut stdin, stdout);

    let is_alive = interact.spawn(opts).expect("Failed to start interact");

    if !is_alive {
        println!("The process was exited");
        #[cfg(unix)]
        println!("Status={:?}", interact.get_status());
    }

    stdin.close().unwrap();

    println!("RESULTS");
    println!(
        "Number of time 'Y' was pressed = {}",
        state.pressed_yes_on_continue.unwrap_or_default()
    );
    println!(
        "Status counter = {}",
        state.stutus_verification_counter.unwrap_or_default()
    );
}
source§

impl<S, I, O, C, IF, OF, IA, OA> InteractOptions<C, IF, OF, IA, OA, NoAction<Session<OsProcess, S>, I, O, C>>

source

pub fn on_idle<F>(self, action: F) -> InteractOptions<C, IF, OF, IA, OA, F>where F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool, Error>,

Puts a handler which will be called on each interaction when no input is detected.

Trait Implementations§

source§

impl<C: Debug, IF: Debug, OF: Debug, IA: Debug, OA: Debug, WA: Debug> Debug for InteractOptions<C, IF, OF, IA, OA, WA>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S, I, O> Default for InteractOptions<(), NoFilter, NoFilter, NoAction<Session<OsProcess, S>, I, O, ()>, NoAction<Session<OsProcess, S>, I, O, ()>, NoAction<Session<OsProcess, S>, I, O, ()>>

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<C, IF, OF, IA, OA, WA> RefUnwindSafe for InteractOptions<C, IF, OF, IA, OA, WA>where C: RefUnwindSafe, IA: RefUnwindSafe, IF: RefUnwindSafe, OA: RefUnwindSafe, OF: RefUnwindSafe, WA: RefUnwindSafe,

§

impl<C, IF, OF, IA, OA, WA> Send for InteractOptions<C, IF, OF, IA, OA, WA>where C: Send, IA: Send, IF: Send, OA: Send, OF: Send, WA: Send,

§

impl<C, IF, OF, IA, OA, WA> Sync for InteractOptions<C, IF, OF, IA, OA, WA>where C: Sync, IA: Sync, IF: Sync, OA: Sync, OF: Sync, WA: Sync,

§

impl<C, IF, OF, IA, OA, WA> Unpin for InteractOptions<C, IF, OF, IA, OA, WA>where C: Unpin, IA: Unpin, IF: Unpin, OA: Unpin, OF: Unpin, WA: Unpin,

§

impl<C, IF, OF, IA, OA, WA> UnwindSafe for InteractOptions<C, IF, OF, IA, OA, WA>where C: UnwindSafe, IA: UnwindSafe, IF: UnwindSafe, OA: UnwindSafe, OF: UnwindSafe, WA: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.