Skip to content

Commit

Permalink
Merge pull request #68 from zhiburt/patch-move-back-to-trait-based-ve…
Browse files Browse the repository at this point in the history
…rsion

[WIP] Move to trait based version `Expect`
  • Loading branch information
zhiburt authored Mar 3, 2024
2 parents e8b43ff + e8846eb commit a0f4f78
Show file tree
Hide file tree
Showing 36 changed files with 2,179 additions and 1,392 deletions.
11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ keywords = ["expect", "pty", "testing", "terminal", "automation"]
readme = "README.md"

[features]
# "pooling" feature works only for not async version
# "pooling" feature works only for not async version on UNIX
polling = ["dep:polling", "dep:crossbeam-channel"]
async = ["futures-lite", "futures-timer", "async-io", "blocking"]

Expand All @@ -36,3 +36,12 @@ crossbeam-channel = { version = "0.5.6", optional = true }

[package.metadata.docs.rs]
all-features = false

[[target.'cfg(unix)'.example]]
name = "log"
path = "examples/log.rs"

[[target.'cfg(windows)'.example]]
name = "powershell"
path = "examples/powershell.rs"

41 changes: 23 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ expectrl = "0.7"
An example where the program simulates a used interacting with `ftp`.

```rust
use expectrl::{spawn, Regex, Eof, Error};
use expectrl::{Regex, Eof, Error, Expect};

fn main() -> Result<(), Error> {
let mut p = spawn("ftp speedtest.tele2.net")?;
let mut p = expectrl::spawn("ftp speedtest.tele2.net")?;
p.expect(Regex("Name \\(.*\\):"))?;
p.send_line("anonymous")?;
p.expect("Password")?;
Expand All @@ -46,6 +46,7 @@ fn main() -> Result<(), Error> {
p.expect(Regex("[0-9]+ \"/upload\""))?;
p.send_line("exit")?;
p.expect(Eof)?;

Ok(())
}
```
Expand All @@ -54,31 +55,34 @@ The same example but the password will be read from stdin.

```rust
use std::io::stdout;

use expectrl::{
interact::{actions::lookup::Lookup, InteractOptions},
spawn, stream::stdin::Stdin,
ControlCode, Error, Regex,
interact::{actions::lookup::Lookup, InteractSession},
stream::stdin::Stdin,
ControlCode, Error, Expect, Regex,
};

fn main() -> Result<(), Error> {
let mut p = expectrl::spawn("ftp bks4-speedtest-1.tele2.net")?;

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);
}
let mut stdin = Stdin::open()?;

Ok(false)
});
InteractSession::new(&mut p, &mut stdin, stdout(), &mut auth)
.set_output_action(move |ctx| {
if login_lookup
.on(ctx.buf, ctx.eof, "Login successful")?
.is_some()
{
**ctx.state = true;
return Ok(true);
}

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

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

if !auth {
Expand All @@ -93,6 +97,7 @@ fn main() -> Result<(), Error> {
p.expect(Regex("[0-9]+ \"/upload\""))?;
p.send(ControlCode::EndOfTransmission)?;
p.expect("Goodbye.")?;

Ok(())
}
```
Expand Down
3 changes: 2 additions & 1 deletion examples/bash.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// An example is based on README.md from https://github.com/philippkeller/rexpect

#[cfg(unix)]
use expectrl::{repl::spawn_bash, ControlCode, Regex};
use expectrl::{repl::spawn_bash, ControlCode, Expect, Regex};

#[cfg(unix)]
#[cfg(not(feature = "async"))]
Expand Down Expand Up @@ -40,6 +40,7 @@ fn main() {
#[cfg(unix)]
#[cfg(feature = "async")]
fn main() {
use expectrl::AsyncExpect;
use futures_lite::io::AsyncBufReadExt;

futures_lite::future::block_on(async {
Expand Down
12 changes: 7 additions & 5 deletions examples/check.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use expectrl::{check, spawn, Error};
use expectrl::{check, spawn, Error, Expect};

#[cfg(not(feature = "async"))]
fn main() {
let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");
let mut p = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");

loop {
match check!(
&mut session,
&mut p,
_ = "Password: " => {
println!("Set password to SECURE_PASSWORD");
session.send_line("SECURE_PASSWORD").unwrap();
p.send_line("SECURE_PASSWORD").unwrap();
},
_ = "Continue [y/n]:" => {
println!("Stop processing");
session.send_line("n").unwrap();
p.send_line("n").unwrap();
},
) {
Err(Error::Eof) => break,
Expand All @@ -24,6 +24,8 @@ fn main() {

#[cfg(feature = "async")]
fn main() {
use expectrl::AsyncExpect;

futures_lite::future::block_on(async {
let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session");

Expand Down
8 changes: 5 additions & 3 deletions examples/expect_line.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use expectrl::{self, Any, Eof};
use expectrl::{self, Any, Eof, Expect};

#[cfg(not(feature = "async"))]
fn main() {
let mut session = expectrl::spawn("ls -al").expect("Can't spawn a session");
let mut p = expectrl::spawn("ls -al").expect("Can't spawn a session");

loop {
let m = session
let m = p
.expect(Any::boxed(vec![
Box::new("\r"),
Box::new("\n"),
Expand All @@ -31,6 +31,8 @@ fn main() {
#[cfg(feature = "async")]
fn main() {
futures_lite::future::block_on(async {
use expectrl::AsyncExpect;

let mut session = expectrl::spawn("ls -al").expect("Can't spawn a session");

loop {
Expand Down
2 changes: 1 addition & 1 deletion examples/ftp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use expectrl::{spawn, ControlCode, Error, Regex};
use expectrl::{spawn, ControlCode, Error, Expect, Regex};

#[cfg(not(feature = "async"))]
fn main() -> Result<(), Error> {
Expand Down
37 changes: 19 additions & 18 deletions examples/ftp_interact.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
use expectrl::{
interact::{actions::lookup::Lookup, InteractOptions},
spawn,
stream::stdin::Stdin,
ControlCode, Error, Regex,
interact::actions::lookup::Lookup, spawn, stream::stdin::Stdin, ControlCode, Error, Expect,
Regex,
};
use std::io::stdout;

#[cfg(not(all(windows, feature = "polling")))]
#[cfg(not(feature = "async"))]
fn main() -> Result<(), Error> {
let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?;

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 stdin = Stdin::open()?;

let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?;
p.interact(&mut stdin, stdout())
.with_state(&mut auth)
.set_output_action(move |ctx| {
if login_lookup
.on(ctx.buf, ctx.eof, "Login successful")?
.is_some()
{
**ctx.state = true;
return Ok(true);
}

Ok(false)
})
.spawn()?;

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

if !auth {
Expand Down
28 changes: 14 additions & 14 deletions examples/interact.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! To run an example run `cargo run --example interact`.
use expectrl::{interact::InteractOptions, spawn, stream::stdin::Stdin};
use expectrl::{spawn, stream::stdin::Stdin};
use std::io::stdout;

#[cfg(unix)]
Expand All @@ -20,7 +20,7 @@ fn main() {
let mut stdin = Stdin::open().expect("Failed to create stdin");

sh.interact(&mut stdin, stdout())
.spawn(&mut InteractOptions::default())
.spawn()
.expect("Failed to start interact");

stdin.close().expect("Failed to close a stdin");
Expand All @@ -30,23 +30,23 @@ fn main() {

#[cfg(feature = "async")]
fn main() {
futures_lite::future::block_on(async {
let mut sh = spawn(SHELL).expect("Error while spawning sh");
// futures_lite::future::block_on(async {
// let mut sh = spawn(SHELL).expect("Error while spawning sh");

println!("Now you're in interacting mode");
println!("To return control back to main type CTRL-] combination");
// println!("Now you're in interacting mode");
// println!("To return control back to main type CTRL-] combination");

let mut stdin = Stdin::open().expect("Failed to create stdin");
// let mut stdin = Stdin::open().expect("Failed to create stdin");

sh.interact(&mut stdin, stdout())
.spawn(&mut InteractOptions::default())
.await
.expect("Failed to start interact");
// sh.interact(&mut stdin, stdout())
// .spawn()
// .await
// .expect("Failed to start interact");

stdin.close().expect("Failed to close a stdin");
// stdin.close().expect("Failed to close a stdin");

println!("Exiting");
});
// println!("Exiting");
// });
}

#[cfg(all(windows, feature = "polling", not(feature = "async")))]
Expand Down
Loading

0 comments on commit a0f4f78

Please sign in to comment.