### Rust: Asynchronous FTP Session with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt Illustrates how to perform asynchronous operations with expectrl, specifically for automating an FTP session. This example requires the 'async' feature to be enabled and uses `async`/`await` syntax with `futures_lite` to block on the async function. ```rust // Enable with: features = ["async"] use expectrl::{spawn, AsyncExpect, Regex, Error}; async fn ftp_example() -> Result<(), Error> { let mut p = spawn("ftp speedtest.tele2.net")?; // All operations are async p.expect(Regex(r"Name \(.*\):\)).await?; p.send_line("anonymous").await?; p.expect("Password").await?; p.send_line("test").await?; p.expect("ftp>").await?; p.send_line("quit").await?; Ok(()) } fn main() { futures_lite::future::block_on(ftp_example()).unwrap(); } ``` -------------------------------- ### Advanced Interactive Session with Stdin/Stdout in Rust Source: https://github.com/zhiburt/expectrl/blob/main/README.md This Rust example showcases an advanced use of expectrl for interactive sessions, integrating standard input and output streams. It demonstrates how to use `InteractSession` to monitor process output for specific patterns (like 'Login successful') and dynamically control the interaction flow, including reading passwords from stdin. ```rust use std::io::stdout; use expectrl::{ 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 search = Lookup::new(); let mut stdin = Stdin::open()?; let authenticated = { let mut session = InteractSession::new(&mut p, &mut stdin, stdout(), false); session.set_output_action(move |ctx| { let found = search.on(ctx.buf, ctx.eof, "Login successful")?; if found.is_some() { *ctx.state = true; return Ok(true); } Ok(false) }); session.spawn()?; session.into_state() }; stdin.close()?; if !authenticated { println!("An authentication 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(()) } ``` -------------------------------- ### Rust: Capturing Match Results with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates how to use the Captures struct in expectrl to access match results. It shows how to retrieve the content before a match, the full matched string, individual capture groups, and iterate over all matches. This example uses synchronous operations. ```rust use expectrl::{spawn, Expect, Regex, Error}; fn main() -> Result<(), Error> { let mut p = spawn("echo 'prefix: key1=value1, key2=value2'")?; let captures = p.expect(Regex(r"(\w+)=(\w+), (\w+)=(\w+)"))?; // Get content before the match let before = String::from_utf8_lossy(captures.before()); println!("Before match: '{}'", before); // Get full matched content let full_match = String::from_utf8_lossy(captures.get(0).unwrap()); println!("Full match: {}", full_match); // Get specific capture groups println!("Key1: {}", String::from_utf8_lossy(captures.get(1).unwrap())); println!("Value1: {}", String::from_utf8_lossy(captures.get(2).unwrap())); // Iterate over all matches for (i, m) in captures.matches().enumerate() { println!("Group {}: {}", i, String::from_utf8_lossy(m)); } // Use index syntax println!("Using index: {}", String::from_utf8_lossy(&captures[0])); // Get all bytes involved println!("All bytes: {:?}", captures.as_bytes()); Ok(()) } ``` -------------------------------- ### Filter Input and Output in InteractSession Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates how to use input and output filters with InteractSession to transform data. Input filters modify data before it's sent, and output filters modify data after it's received. This example shows converting input to uppercase and prefixing output. ```rust use expectrl::{spawn, stream::stdin::Stdin, Error}; use std::{borrow::Cow, io::stdout}; fn main() -> Result<(), Error> { let mut sh = spawn("cat")?; let mut stdin = Stdin::open()?; sh.interact(&mut stdin, stdout()) // Filter input: convert to uppercase .set_input_filter(|input| { let upper: Vec = input.iter() .map(|b| b.to_ascii_uppercase()) .collect(); Ok(Cow::Owned(upper)) }) // Filter output: add prefix to each chunk .set_output_filter(|output| { let mut prefixed = b"[OUT] ".to_vec(); prefixed.extend_from_slice(output); Ok(Cow::Owned(prefixed)) }) .spawn()?; stdin.close()?; Ok(()) } ``` -------------------------------- ### Expectrl Process Automation Source: https://github.com/zhiburt/expectrl/blob/main/README.md Demonstrates how to spawn a process, send commands, and expect specific output patterns using the Expectrl library. ```APIDOC ## Rust Library Usage: expectrl ### Description This library allows developers to automate interactive terminal applications by spawning processes and interacting with their standard input and output streams. ### Method N/A (Library API) ### Endpoint expectrl::spawn(command: &str) ### Parameters #### Path Parameters - **command** (string) - Required - The shell command to execute as a child process. ### Request Example let mut p = expectrl::spawn("ftp speedtest.tele2.net")?; ### Response #### Success Response (Result) - **p** (Session) - An interactive session object representing the child process. #### Response Example p.expect("ftp>")?; p.send_line("exit")?; ``` -------------------------------- ### Custom REPL Wrapper with ReplSession Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates how to wrap any interactive session with `ReplSession` for custom prompt handling, enabling automation of various REPL-style applications like Node.js. It includes setting quit commands and executing code. ```rust use expectrl::{spawn, repl::ReplSession, Expect, Error}; fn main() -> Result<(), Error> { // Spawn a custom REPL (e.g., node.js) let session = spawn("node")?; // Wrap with ReplSession using node's prompt let mut node = ReplSession::new(session, "> "); node.set_quit_command(".exit"); // Wait for initial prompt node.expect_prompt()?; // Execute JavaScript let output = node.execute("2 + 2")?; println!("2 + 2 = {}", String::from_utf8_lossy(&output).trim()); let output = node.execute("Math.sqrt(16)")?; println!("sqrt(16) = {}", String::from_utf8_lossy(&output).trim()); // Clean exit node.exit()?; Ok(()) } ``` -------------------------------- ### Spawn Process with std::process::Command using Session::spawn Source: https://context7.com/zhiburt/expectrl/llms.txt Illustrates spawning a process session using `Session::spawn` with a `std::process::Command`. This method allows for more granular control over process creation, including setting environment variables and working directories. It also demonstrates expecting specific output from the spawned process. ```rust use std::process::Command; use expectrl::{Session, Expect, Error}; fn main() -> Result<(), Error> { // Create a command with custom environment let mut cmd = Command::new("sh"); cmd.arg("-c").arg("echo $MY_VAR"); cmd.env("MY_VAR", "Hello from environment!"); // Spawn session with the configured command let mut p = Session::spawn(cmd)?; // Expect the output let output = p.expect("Hello from environment!")?; println!("Matched: {:?}", String::from_utf8_lossy(output.get(0).unwrap())); Ok(()) } ``` -------------------------------- ### Spawn Bash Session with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt Shows how to spawn and interact with a preconfigured Bash shell session using `spawn_bash`. This includes executing commands, matching output with regex, handling long-running commands, and exiting the session cleanly. ```rust use expectrl::{repl::spawn_bash, Expect, Regex, ControlCode, Error}; fn main() -> Result<(), Error> { let mut bash = spawn_bash()?; // Execute a command and get output let output = bash.execute("hostname")?; println!("Hostname: {}", String::from_utf8_lossy(&output)); // Run command with regex matching bash.send_line("wc -l /etc/passwd")?; let found = bash.expect(Regex(r"(\d+)"))?; let lines = String::from_utf8_lossy(found.get(1).unwrap()); println!("Lines in /etc/passwd: {}", lines); bash.expect_prompt()?; // Run long-running command and read output incrementally bash.send_line("ping -c 3 localhost")?; for _ in 0..3 { let time = bash.expect(Regex(r"time=([0-9.]+ ms)"))?; println!("Ping: {}", String::from_utf8_lossy(time.get(1).unwrap())); } bash.expect_prompt()?; // Clean exit bash.exit()?; Ok(()) } ``` -------------------------------- ### Basic FTP Interaction with Expectrl in Rust Source: https://github.com/zhiburt/expectrl/blob/main/README.md This Rust code snippet demonstrates a basic automation of an FTP client using the expectrl library. It spawns an FTP process, sends login credentials, navigates directories, and retrieves the current directory, showcasing expectrl's ability to interact with a child process's input and output. ```rust use expectrl::{Regex, Eof, Error, Expect}; fn main() -> Result<(), Error> { let mut p = expectrl::spawn("ftp speedtest.tele2.net")?; p.expect(Regex("Name \(.*\):?"))?; p.send_line("anonymous")?; p.expect("Password")?; p.send_line("test")?; p.expect("ftp>")?; p.send_line("cd upload")?; p.expect("successfully changed.\r\nftp>")?; p.send_line("pwd")?; p.expect(Regex("[0-9]+ \"/upload\""))?; p.send_line("exit")?; p.expect(Eof)?; Ok(()) } ``` -------------------------------- ### Spawn a New Process Session with expectrl::spawn Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates spawning a child process using the `spawn` function from the expectrl library. It shows how to send input to the process and implies interaction with its output streams. This is a fundamental step for automating terminal applications. ```rust use expectrl::{spawn, Expect, Error}; fn main() -> Result<(), Error> { // Spawn a simple process let mut p = spawn("cat")?; // Send input to the process p.send_line("Hello World")?; // Read output (the process echoes input back) // Cat will echo what we send Ok(()) } ``` -------------------------------- ### Enable I/O Logging with log Function Source: https://context7.com/zhiburt/expectrl/llms.txt Explains how to use the `log` function to wrap a session and log all read/write operations to a specified writer, such as stdout or a file. This is useful for debugging and auditing interactive session behavior. ```rust use expectrl::{spawn, session::log, Expect, Error}; use std::io::stdout; fn main() -> Result<(), Error> { // Create session with logging to stdout let p = spawn("cat")?; let mut p = log(p, stdout())?; // All I/O will be logged p.send_line("Hello")?; p.expect("Hello")?; // Log to file instead let p = spawn("cat")?; let file = std::fs::File::create("/tmp/session.log")?; let mut p = log(p, file)?; p.send_line("Logged to file")?; p.expect("Logged")?; Ok(()) } ``` -------------------------------- ### Spawn Python IDLE Session with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt Illustrates spawning and automating a Python interpreter session using `spawn_python`. This covers executing Python statements, retrieving computation results, handling multi-line code input, and exiting the interpreter. ```rust use expectrl::{repl::spawn_python, Expect, Error}; fn main() -> Result<(), Error> { let mut python = spawn_python()?; // Execute Python statements let _ = python.execute("x = 10")?; let _ = python.execute("y = 20")?; // Get computation result let output = python.execute("print(x + y)")?; println!("Result: {}", String::from_utf8_lossy(&output).trim()); // Output: Result: 30 // Execute multi-line code python.send_line("for i in range(3):")?; python.expect("... ")?; let output = python.execute(" print(f'Count: {i}')")?; println!("{}", String::from_utf8_lossy(&output)); // Exit Python python.exit()?; Ok(()) } ``` -------------------------------- ### ReplSession - Custom REPL Wrapper Source: https://context7.com/zhiburt/expectrl/llms.txt Wraps any session with custom prompt handling for automating REPL applications. ```APIDOC ## ReplSession - Custom REPL Wrapper ### Description The `ReplSession` struct wraps any session with custom prompt handling, enabling automation of any REPL-style application. ### Method `ReplSession::new(session, prompt)` ### Endpoint N/A (Works with any spawned session) ### Parameters #### Path Parameters - **`session`** (`Session`) - The existing session to wrap. - **`prompt`** (`&str`) - The expected prompt string for the REPL. #### Query Parameters None #### Request Body None ### Request Example ```rust use expectrl::{spawn, repl::ReplSession, Expect, Error}; fn main() -> Result<(), Error> { // Spawn a custom REPL (e.g., node.js) let session = spawn("node")?; // Wrap with ReplSession using node's prompt let mut node = ReplSession::new(session, "> "); node.set_quit_command(".exit"); // Wait for initial prompt node.expect_prompt()?; // Execute JavaScript let output = node.execute("2 + 2")?; println!("2 + 2 = {}", String::from_utf8_lossy(&output).trim()); let output = node.execute("Math.sqrt(16)")?; println!("sqrt(16) = {}", String::from_utf8_lossy(&output).trim()); // Clean exit node.exit()?; Ok(()) } ``` ### Response #### Success Response (200) N/A (This is a wrapper, not a direct request/response endpoint) #### Response Example N/A ``` -------------------------------- ### log - Enable I/O Logging Source: https://context7.com/zhiburt/expectrl/llms.txt Wraps a session to log all read/write operations. ```APIDOC ## log - Enable I/O Logging ### Description The `log` function wraps a session to log all read/write operations to a specified writer, useful for debugging and auditing. ### Method `log(session, writer)` ### Endpoint N/A (In-memory session wrapping) ### Parameters #### Path Parameters - **`session`** (`impl Session`) - The session to wrap. - **`writer`** (`impl Write`) - The writer to log I/O operations to. #### Query Parameters None #### Request Body None ### Request Example ```rust use expectrl::{spawn, session::log, Expect, Error}; use std::io::stdout; fn main() -> Result<(), Error> { // Create session with logging to stdout let p = spawn("cat")?; let mut p = log(p, stdout())?; // All I/O will be logged p.send_line("Hello")?; p.expect("Hello")?; // Log to file instead let p = spawn("cat")?; let file = std::fs::File::create("/tmp/session.log")?; let mut p = log(p, file)?; p.send_line("Logged to file")?; p.expect("Logged")?; Ok(()) } ``` ### Response #### Success Response (200) N/A (This function returns a logged session object) #### Response Example N/A ``` -------------------------------- ### Input and Output Filters Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates how to use input and output filters with InteractSession to transform data. ```APIDOC ## Input and Output Filters ### Description The `InteractSession` supports input and output filters to transform data passing through the session. ### Method `InteractSession::interact()` with `.set_input_filter()` and `.set_output_filter()` ### Endpoint N/A (In-memory session manipulation) ### Parameters #### Input Filter - **`input`** (closure) - Takes a byte slice and returns a `Result, Error>`. - **`output`** (closure) - Takes a byte slice and returns a `Result, Error>`. ### Request Example ```rust use expectrl::{spawn, stream::stdin::Stdin, Error}; use std::{borrow::Cow, io::stdout}; fn main() -> Result<(), Error> { let mut sh = spawn("cat")?; let mut stdin = Stdin::open()?; sh.interact(&mut stdin, stdout()) // Filter input: convert to uppercase .set_input_filter(|input| { let upper: Vec = input.iter() .map(|b| b.to_ascii_uppercase()) .collect(); Ok(Cow::Owned(upper)) }) // Filter output: add prefix to each chunk .set_output_filter(|output| { let mut prefixed = b"[OUT] ".to_vec(); prefixed.extend_from_slice(output); Ok(Cow::Owned(prefixed)) }) .spawn()?; stdin.close()?; Ok(()) } ``` ### Response #### Success Response (200) N/A (This is a configuration step, not a direct request/response) #### Response Example N/A ``` -------------------------------- ### spawn_python - Python IDLE Session Source: https://context7.com/zhiburt/expectrl/llms.txt Creates and interacts with a Python interpreter session. ```APIDOC ## spawn_python - Python IDLE Session ### Description The `spawn_python` function creates a Python interpreter session with prompt handling for automated Python scripting. ### Method `spawn_python()` ### Endpoint N/A (Spawns a local process) ### Parameters None ### Request Example ```rust use expectrl::{repl::spawn_python, Expect, Error}; fn main() -> Result<(), Error> { let mut python = spawn_python()?; // Execute Python statements let _ = python.execute("x = 10")?; let _ = python.execute("y = 20")?; // Get computation result let output = python.execute("print(x + y)")?; println!("Result: {}", String::from_utf8_lossy(&output).trim()); // Output: Result: 30 // Execute multi-line code python.send_line("for i in range(3):")?; python.expect("... ")?; let output = python.execute(" print(f'Count: {i}')")?; println!("{}", String::from_utf8_lossy(&output)); // Exit Python python.exit()?; Ok(()) } ``` ### Response #### Success Response (200) N/A (This function returns a session object) #### Response Example N/A ``` -------------------------------- ### Async Session Operations Source: https://context7.com/zhiburt/expectrl/llms.txt Details how to perform asynchronous operations using the async feature, compatible with runtimes like tokio or async-std. ```APIDOC ## Async Session Operations ### Description When the `async` feature is enabled, all session operations (expect, send_line, etc.) become asynchronous, allowing for non-blocking terminal automation. ### Requirements - Enable feature: `features = ["async"]` ### Example ```rust use expectrl::{spawn, AsyncExpect, Regex, Error}; async fn ftp_example() -> Result<(), Error> { let mut p = spawn("ftp speedtest.tele2.net")?; p.expect(Regex(r"Name \(.*\):")).await?; p.send_line("anonymous").await?; Ok(()) } ``` ``` -------------------------------- ### spawn_bash - Bash Shell Session Source: https://context7.com/zhiburt/expectrl/llms.txt Creates and interacts with a preconfigured bash session. ```APIDOC ## spawn_bash - Bash Shell Session ### Description The `spawn_bash` function creates a preconfigured bash session with custom prompt handling, ideal for automated shell scripting. ### Method `spawn_bash()` ### Endpoint N/A (Spawns a local process) ### Parameters None ### Request Example ```rust use expectrl::{repl::spawn_bash, Expect, Regex, ControlCode, Error}; fn main() -> Result<(), Error> { let mut bash = spawn_bash()?; // Execute a command and get output let output = bash.execute("hostname")?; println!("Hostname: {}", String::from_utf8_lossy(&output)); // Run command with regex matching bash.send_line("wc -l /etc/passwd")?; let found = bash.expect(Regex(r"(\d+)"))?; let lines = String::from_utf8_lossy(found.get(1).unwrap()); println!("Lines in /etc/passwd: {}", lines); bash.expect_prompt()?; // Run long-running command and read output incrementally bash.send_line("ping -c 3 localhost")?; for _ in 0..3 { let time = bash.expect(Regex(r"time=([0-9.]+ ms)"))?; println!("Ping: {}", String::from_utf8_lossy(time.get(1).unwrap())); } bash.expect_prompt()?; // Clean exit bash.exit()?; Ok(()) } ``` ### Response #### Success Response (200) N/A (This function returns a session object) #### Response Example N/A ``` -------------------------------- ### Wait for Pattern Match with expect method Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates the `expect` method for blocking until a pattern is found in the process output or a timeout occurs. It supports matching literal strings and regular expressions, including capturing groups. The matched content can be accessed after a successful match. ```rust use expectrl::{spawn, Expect, Regex, Error}; use std::time::Duration; fn main() -> Result<(), Error> { let mut p = spawn("echo 'User: John, Age: 25'")?; // Expect a simple string p.expect("User:")?; // Expect with regex to capture groups let captures = p.expect(Regex(r"(\w+), Age: (\d+)"))?; // Access matched content let name = String::from_utf8_lossy(captures.get(1).unwrap()); let age = String::from_utf8_lossy(captures.get(2).unwrap()); println!("Name: {}, Age: {}", name, age); // Output: Name: John, Age: 25 Ok(()) } ``` -------------------------------- ### Create Interactive Sessions with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt The interact method bridges the spawned process with standard input and output. This allows for manual user control or programmatic interaction via callbacks. ```rust use expectrl::{spawn, stream::stdin::Stdin}; use std::io::stdout; fn main() { let mut sh = spawn("sh").expect("Failed to spawn shell"); let mut stdin = Stdin::open().expect("Failed to open stdin"); sh.interact(&mut stdin, stdout()) .spawn() .expect("Failed to start interaction"); stdin.close().expect("Failed to close stdin"); } ``` -------------------------------- ### Match Any of Multiple Patterns in Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt The Any needle allows matching against a list of alternative patterns. It supports both static string slices and boxed dynamic needle types for flexible pattern detection. ```rust use expectrl::{spawn, Expect, Any, NBytes, Error}; fn main() -> Result<(), Error> { let mut p = spawn("echo 'success'")?; let captures = p.expect(Any(["success", "failure", "error"]))?; println!("Matched: {}", String::from_utf8_lossy(captures.get(0).unwrap())); let mut p = spawn("echo 'test'")?; let captures = p.expect(Any::boxed(vec![ Box::new("error"), Box::new(NBytes(4)), ]))?; println!("Matched: {}", String::from_utf8_lossy(captures.get(0).unwrap())); Ok(()) } ``` -------------------------------- ### Implement InteractSession with Callbacks Source: https://context7.com/zhiburt/expectrl/llms.txt InteractSession supports stateful callbacks, enabling pattern detection and conditional logic during an interactive session. This is useful for automating authentication or responding to specific output events. ```rust use expectrl::{ interact::actions::lookup::Lookup, spawn, stream::stdin::Stdin, Error, Expect, }; use std::io::stdout; fn main() -> Result<(), Error> { let mut p = spawn("ftp speedtest.tele2.net")?; let mut authenticated = false; let mut lookup = Lookup::new(); let mut stdin = Stdin::open()?; p.interact(&mut stdin, stdout()) .with_state(&mut authenticated) .set_output_action(move |ctx| { if lookup.on(ctx.buf, ctx.eof, "Login successful")?.is_some() { **ctx.state = true; return Ok(true); } Ok(false) }) .spawn()?; stdin.close()?; Ok(()) } ``` -------------------------------- ### Send Data to Process with expectrl::send Source: https://context7.com/zhiburt/expectrl/llms.txt The `send` method writes raw bytes or strings to a process's standard input without appending a line ending. It's useful for sending precise data segments. Dependencies include the `expectrl` crate. ```rust use expectrl::{spawn, Expect, ControlCode, Error}; fn main() -> Result<(), Error> { let mut p = spawn("cat")?; // Send a string p.send("Hello")?; // Send bytes p.send(b" World")?; // Send control codes (Ctrl+D for EOF) p.send(ControlCode::EndOfTransmission)?; Ok(()) } ``` -------------------------------- ### Regex Pattern Matching with expectrl::Regex Source: https://context7.com/zhiburt/expectrl/llms.txt The `Regex` needle enables powerful pattern matching using regular expressions, including support for capture groups. This allows for extracting specific information from process output. Requires `expectrl` crate. ```rust use expectrl::{spawn, Expect, Regex, Error}; fn main() -> Result<(), Error> { let mut p = spawn("echo 'error: file not found at /path/to/file.txt'")?; // Match with capture groups let captures = p.expect(Regex(r"error: (.+) at (.+)"))?; // Get the full match println!("Full match: {}", String::from_utf8_lossy(captures.get(0).unwrap())); // Get capture groups println!("Error message: {}", String::from_utf8_lossy(captures.get(1).unwrap())); println!("File path: {}", String::from_utf8_lossy(captures.get(2).unwrap())); // Output: // Full match: error: file not found at /path/to/file.txt // Error message: file not found // File path: /path/to/file.txt Ok(()) } ``` -------------------------------- ### Configure Lazy Matching with expectrl::set_expect_lazy Source: https://context7.com/zhiburt/expectrl/llms.txt The `set_expect_lazy` method toggles between greedy (default) and lazy matching algorithms for `expect`. Lazy matching returns as soon as a pattern is found, while greedy matching consumes all available data first. Requires `expectrl` and `std::thread`/`std::time::Duration` for demonstration. ```rust use expectrl::{spawn, Expect, Regex, Error}; use std::{thread, time::Duration}; fn main() -> Result<(), Error> { // Greedy matching (default) - matches all digits let mut p = spawn("echo 12345")?; thread::sleep(Duration::from_millis(100)); let m = p.expect(Regex(r"\d+"))?; println!("Greedy: {}", String::from_utf8_lossy(m.get(0).unwrap())); // Output: Greedy: 12345 // Lazy matching - matches minimum required let mut p = spawn("echo 12345")?; p.set_expect_lazy(true); let m = p.expect(Regex(r"\d+"))?; println!("Lazy: {}", String::from_utf8_lossy(m.get(0).unwrap())); // Output: Lazy: 1 Ok(()) } ``` -------------------------------- ### Non-blocking Pattern Check with check method Source: https://context7.com/zhiburt/expectrl/llms.txt Shows the `check` method for non-blocking pattern verification against available buffer data. It returns immediately, indicating whether a pattern was found without consuming the matched bytes. This is useful for polling or checking status without halting execution. ```rust use expectrl::{spawn, Expect, Regex, Error}; use std::{thread, time::Duration}; fn main() -> Result<(), Error> { let mut p = spawn("sh -c 'sleep 0.1 && echo ready'")?; // Give the process time to produce output thread::sleep(Duration::from_millis(200)); // Non-blocking check for pattern let found = p.check("ready")?; if !found.is_empty() { println!("Process is ready!"); } else { println!("Pattern not found yet"); } Ok(()) } ``` -------------------------------- ### Send Data with Line Ending using expectrl::send_line Source: https://context7.com/zhiburt/expectrl/llms.txt The `send_line` method sends data to a process's stdin, automatically appending a platform-appropriate line ending. This is convenient for sending complete lines of input. It requires the `expectrl` crate. ```rust use expectrl::{spawn, Expect, Error}; fn main() -> Result<(), Error> { let mut p = spawn("cat")?; // Send multiple lines p.send_line("Line 1")?; p.send_line("Line 2")?; p.send_line("Line 3")?; // Each line will be echoed back by cat p.expect("Line 1")?; p.expect("Line 2")?; p.expect("Line 3")?; Ok(()) } ``` -------------------------------- ### Match Specific Number of Bytes with expectrl::NBytes Source: https://context7.com/zhiburt/expectrl/llms.txt The `NBytes` needle matches a precise number of bytes from the process's output stream. This is useful for reading fixed-size data chunks. Requires the `expectrl` crate. ```rust use expectrl::{spawn, Expect, NBytes, Error}; fn main() -> Result<(), Error> { let mut p = spawn("echo -n 'ABCDEFGHIJ'")?; // Match exactly 5 bytes let captures = p.expect(NBytes(5))?; println!("First 5 bytes: {}", String::from_utf8_lossy(captures.get(0).unwrap())); // Output: First 5 bytes: ABCDE // Match next 5 bytes let captures = p.expect(NBytes(5))?; println!("Next 5 bytes: {}", String::from_utf8_lossy(captures.get(0).unwrap())); // Output: Next 5 bytes: FGHIJ Ok(()) } ``` -------------------------------- ### Captures - Match Result Handling Source: https://context7.com/zhiburt/expectrl/llms.txt Explains how to access and manipulate match results using the Captures struct, including accessing specific groups and content before the match. ```APIDOC ## Captures - Match Result Container ### Description The `Captures` struct provides methods to access matched content, the buffer before the match, and individual capture groups from a regex match. ### Usage - `captures.before()`: Returns the bytes preceding the match. - `captures.get(index)`: Retrieves a specific capture group by index. - `captures.matches()`: Returns an iterator over all capture groups. ### Example ```rust let captures = p.expect(Regex(r"(\w+)=(\w+), (\w+)=(\w+)"))?; let full_match = String::from_utf8_lossy(captures.get(0).unwrap()); ``` ``` -------------------------------- ### Configure Expectation Timeout with expectrl::set_expect_timeout Source: https://context7.com/zhiburt/expectrl/llms.txt The `set_expect_timeout` method allows configuration of the maximum duration `expect` will wait for a pattern match before returning an `ExpectTimeout` error. Setting it to `None` disables the timeout. Requires `expectrl` and `std::time::Duration`. ```rust use expectrl::{spawn, Expect, Error}; use std::time::Duration; fn main() -> Result<(), Error> { let mut p = spawn("cat")?; // Set 5 second timeout p.set_expect_timeout(Some(Duration::from_secs(5))); // This will timeout after 5 seconds if no input received match p.expect("pattern") { Ok(captures) => println!("Found!"), Err(Error::ExpectTimeout) => println!("Timed out waiting for pattern"), Err(e) => return Err(e), } // Disable timeout (wait indefinitely) p.set_expect_timeout(None); Ok(()) } ``` -------------------------------- ### Send Terminal Control Sequences with Expectrl Source: https://context7.com/zhiburt/expectrl/llms.txt The ControlCode enum provides a way to send standard ASCII control signals like Ctrl+C or Ctrl+D to a spawned process. It supports direct enum usage, string notation parsing, and common aliases. ```rust use expectrl::{spawn, Expect, ControlCode, Error}; use std::{thread, time::Duration}; fn main() -> Result<(), Error> { let mut p = spawn("cat")?; p.send_line("Hello")?; thread::sleep(Duration::from_millis(100)); p.send(ControlCode::EndOfText)?; let mut p = spawn("cat")?; p.send_line("data")?; p.send(ControlCode::EndOfTransmission)?; let ctrl_c = ControlCode::try_from("^C").unwrap(); let ctrl_d = ControlCode::try_from("^D").unwrap(); Ok(()) } ``` -------------------------------- ### Check Pattern Without Consuming with is_matched method Source: https://context7.com/zhiburt/expectrl/llms.txt Demonstrates the `is_matched` method, which checks for a pattern in the output buffer without consuming the matched data. This allows the data to be processed again by other methods like `expect` or `check`. It's useful for peeking at output before deciding on further actions. ```rust use expectrl::{spawn, Expect, Regex, Error}; use std::{thread, time::Duration}; fn main() -> Result<(), Error> { let mut p = spawn("cat")?; p.send_line("test123")?; thread::sleep(Duration::from_millis(100)); // Check if pattern exists without consuming if p.is_matched(Regex(r"\d+"))? { println!("Found digits in output"); // The data is still available for expect/check let m = p.expect(Regex(r"\d+"))?; println!("Digits: {}", String::from_utf8_lossy(m.get(0).unwrap())); } Ok(()) } ``` -------------------------------- ### Match End of File with expectrl::Eof Source: https://context7.com/zhiburt/expectrl/llms.txt The `Eof` needle is used to match the end-of-file condition on the process's output stream, which typically occurs when the process terminates. This is useful for ensuring a process has completed its execution. Requires `expectrl` crate. ```rust use expectrl::{spawn, Expect, Eof, Error}; fn main() -> Result<(), Error> { let mut p = spawn("echo 'Hello World'")?; // Wait for process to complete and EOF let captures = p.expect(Eof)?; println!("Process output before EOF: {}", String::from_utf8_lossy(captures.as_bytes())); Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.