#![warn( missing_docs, future_incompatible, single_use_lifetimes, trivial_casts, trivial_numeric_casts, unreachable_pub, unused_extern_crates, unused_import_braces, unused_qualifications, unused_results, unused_variables, variant_size_differences, missing_debug_implementations, rust_2018_idioms )] #![allow(clippy::uninlined_format_args)] //! # A tool for automating terminal applications on alike original expect. //! //! Using the library you can: //! //! - Spawn process //! - Control process //! - Interact with process's IO(input/output). //! //! `expectrl` like original `expect` may shine when you're working with interactive applications. //! If your application is not interactive you may not find the library the best choise. //! //! ## Feature flags //! //! - `async`: Enables a async/await public API. //! - `polling`: Enables polling backend in interact session. Be cautious to use it on windows. //! //! ## Examples //! //! ### An example for interacting via ftp. //! //! ```no_run,ignore //! use expectrl::{spawn, Regex, Eof, WaitStatus}; //! //! let mut p = spawn("ftp speedtest.tele2.net").unwrap(); //! p.expect(Regex("Name \\(.*\\):")).unwrap(); //! p.send_line("anonymous").unwrap(); //! p.expect("Password").unwrap(); //! p.send_line("test").unwrap(); //! p.expect("ftp>").unwrap(); //! p.send_line("cd upload").unwrap(); //! p.expect("successfully changed.\r\nftp>").unwrap(); //! p.send_line("pwd").unwrap(); //! p.expect(Regex("[0-9]+ \"/upload\"")).unwrap(); //! p.send_line("exit").unwrap(); //! p.expect(Eof).unwrap(); //! assert_eq!(p.wait().unwrap(), WaitStatus::Exited(p.pid(), 0)); //! ``` //! //! *The example inspired by the one in [philippkeller/rexpect].* //! //! ### An example when `Command` is used. //! //! ```no_run,ignore //! use std::{process::Command, io::prelude::*}; //! use expectrl::Session; //! //! let mut echo_hello = Command::new("sh"); //! echo_hello.arg("-c").arg("echo hello"); //! //! let mut p = Session::spawn(echo_hello).unwrap(); //! p.expect("hello").unwrap(); //! ``` //! //! ### An example of logging. //! //! ```no_run,ignore //! use std::io::{stdout, prelude::*}; //! use expectrl::{spawn, session::log}; //! //! let mut sh = log(spawn("sh").unwrap(), stdout()).unwrap(); //! //! writeln!(sh, "Hello World").unwrap(); //! ``` //! //! ### An example of `async` feature. //! //! You need to provide a `features=["async"]` flag to use it. //! //! ```no_run,ignore //! use expectrl::spawn; //! //! let mut p = spawn("cat").await.unwrap(); //! p.expect("hello").await.unwrap(); //! ``` //! //! ### An example of interact session with `STDIN` and `STDOUT` //! //! ```no_run,ignore //! use expectrl::{spawn, stream::stdin::Stdin}; //! use std::io::stdout; //! //! let mut sh = spawn("cat").expect("Failed to spawn a 'cat' process"); //! //! let mut stdin = Stdin::open().expect("Failed to create stdin"); //! //! sh.interact(&mut stdin, stdout()) //! .spawn() //! .expect("Failed to start interact session"); //! //! stdin.close().expect("Failed to close a stdin"); //! ``` //! //! [For more examples, check the examples directory.](https://github.com/zhiburt/expectrl/tree/main/examples) mod captures; mod check_macros; mod control_code; mod error; mod needle; #[cfg(all(windows, feature = "polling"))] mod waiter; pub mod interact; pub mod process; pub mod repl; pub mod session; pub mod stream; pub use captures::Captures; pub use control_code::ControlCode; pub use error::Error; pub use needle::{Any, Eof, NBytes, Needle, Regex}; #[cfg(unix)] pub use ptyprocess::{Signal, WaitStatus}; pub use session::Session; /// Spawn spawnes a new session. /// /// It accepts a command and possibly arguments just as string. /// It doesn't parses ENV variables. For complex constrictions use [`Session::spawn`]. /// /// # Example /// /// ```no_run,ignore /// use std::{thread, time::Duration, io::{Read, Write}}; /// use expectrl::{spawn, ControlCode}; /// /// let mut p = spawn("cat").unwrap(); /// p.send_line("Hello World").unwrap(); /// /// thread::sleep(Duration::from_millis(300)); // give 'cat' some time to set up /// p.send(ControlCode::EndOfText).unwrap(); // abort: SIGINT /// /// let mut buf = String::new(); /// p.read_to_string(&mut buf).unwrap(); /// /// assert_eq!(buf, "Hello World\r\n"); /// ``` /// /// [`Session::spawn`]: ./struct.Session.html?#spawn pub fn spawn>(cmd: S) -> Result { Session::spawn_cmd(cmd.as_ref()) }