Skip to content

Commit a5e99df

Browse files
committed
refactor: Move helpers to after use
1 parent a49324a commit a5e99df

2 files changed

Lines changed: 96 additions & 96 deletions

File tree

src/reader.rs

Lines changed: 90 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -8,96 +8,6 @@ use std::sync::mpsc::{Receiver, channel};
88
use std::thread;
99
use std::{fmt, time};
1010

11-
#[derive(Debug)]
12-
enum PipeError {
13-
IO(io::Error),
14-
}
15-
16-
#[derive(Debug)]
17-
#[allow(clippy::upper_case_acronyms)]
18-
enum PipedChar {
19-
Char(u8),
20-
EOF,
21-
}
22-
23-
pub enum ReadUntil {
24-
String(String),
25-
Regex(Regex),
26-
EOF,
27-
NBytes(usize),
28-
Any(Vec<ReadUntil>),
29-
}
30-
31-
impl fmt::Display for ReadUntil {
32-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33-
let printable = match self {
34-
ReadUntil::String(s) if s == "\n" => "\\n (newline)".to_owned(),
35-
ReadUntil::String(s) if s == "\r" => "\\r (carriage return)".to_owned(),
36-
ReadUntil::String(s) => format!("\"{s}\""),
37-
ReadUntil::Regex(r) => format!("Regex: \"{r}\""),
38-
ReadUntil::EOF => "EOF (End of File)".to_owned(),
39-
ReadUntil::NBytes(n) => format!("reading {n} bytes"),
40-
ReadUntil::Any(v) => {
41-
let mut res = Vec::new();
42-
for r in v {
43-
res.push(r.to_string());
44-
}
45-
res.join(", ")
46-
}
47-
};
48-
write!(f, "{printable}")
49-
}
50-
}
51-
52-
/// find first occurrence of needle within buffer
53-
///
54-
/// # Arguments:
55-
///
56-
/// - buffer: the currently read buffer from a process which will still grow in the future
57-
/// - eof: if the process already sent an EOF or a HUP
58-
///
59-
/// # Return
60-
///
61-
/// Tuple with match positions:
62-
/// 1. position before match (0 in case of EOF and Nbytes)
63-
/// 2. position after match
64-
pub fn find(needle: &ReadUntil, buffer: &str, eof: bool) -> Option<(usize, usize)> {
65-
match needle {
66-
ReadUntil::String(s) => buffer.find(s).map(|pos| (pos, pos + s.len())),
67-
ReadUntil::Regex(pattern) => pattern.find(buffer).map(|mat| (mat.start(), mat.end())),
68-
ReadUntil::EOF => {
69-
if eof {
70-
Some((0, buffer.len()))
71-
} else {
72-
None
73-
}
74-
}
75-
ReadUntil::NBytes(n) => {
76-
if *n <= buffer.len() {
77-
Some((0, *n))
78-
} else if eof && !buffer.is_empty() {
79-
// reached almost end of buffer, return string, even though it will be
80-
// smaller than the wished n bytes
81-
Some((0, buffer.len()))
82-
} else {
83-
None
84-
}
85-
}
86-
ReadUntil::Any(anys) => anys
87-
.iter()
88-
// Filter matching needles
89-
.filter_map(|any| find(any, buffer, eof))
90-
// Return the left-most match
91-
.min_by(|(start1, end1), (start2, end2)| {
92-
if start1 == start2 {
93-
end1.cmp(end2)
94-
} else {
95-
start1.cmp(start2)
96-
}
97-
}),
98-
}
99-
}
100-
10111
/// Options for `NBReader`
10212
///
10313
/// - timeout:
@@ -296,6 +206,96 @@ impl NBReader {
296206
}
297207
}
298208

209+
pub enum ReadUntil {
210+
String(String),
211+
Regex(Regex),
212+
EOF,
213+
NBytes(usize),
214+
Any(Vec<ReadUntil>),
215+
}
216+
217+
impl fmt::Display for ReadUntil {
218+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219+
let printable = match self {
220+
ReadUntil::String(s) if s == "\n" => "\\n (newline)".to_owned(),
221+
ReadUntil::String(s) if s == "\r" => "\\r (carriage return)".to_owned(),
222+
ReadUntil::String(s) => format!("\"{s}\""),
223+
ReadUntil::Regex(r) => format!("Regex: \"{r}\""),
224+
ReadUntil::EOF => "EOF (End of File)".to_owned(),
225+
ReadUntil::NBytes(n) => format!("reading {n} bytes"),
226+
ReadUntil::Any(v) => {
227+
let mut res = Vec::new();
228+
for r in v {
229+
res.push(r.to_string());
230+
}
231+
res.join(", ")
232+
}
233+
};
234+
write!(f, "{printable}")
235+
}
236+
}
237+
238+
/// find first occurrence of needle within buffer
239+
///
240+
/// # Arguments:
241+
///
242+
/// - buffer: the currently read buffer from a process which will still grow in the future
243+
/// - eof: if the process already sent an EOF or a HUP
244+
///
245+
/// # Return
246+
///
247+
/// Tuple with match positions:
248+
/// 1. position before match (0 in case of EOF and Nbytes)
249+
/// 2. position after match
250+
pub fn find(needle: &ReadUntil, buffer: &str, eof: bool) -> Option<(usize, usize)> {
251+
match needle {
252+
ReadUntil::String(s) => buffer.find(s).map(|pos| (pos, pos + s.len())),
253+
ReadUntil::Regex(pattern) => pattern.find(buffer).map(|mat| (mat.start(), mat.end())),
254+
ReadUntil::EOF => {
255+
if eof {
256+
Some((0, buffer.len()))
257+
} else {
258+
None
259+
}
260+
}
261+
ReadUntil::NBytes(n) => {
262+
if *n <= buffer.len() {
263+
Some((0, *n))
264+
} else if eof && !buffer.is_empty() {
265+
// reached almost end of buffer, return string, even though it will be
266+
// smaller than the wished n bytes
267+
Some((0, buffer.len()))
268+
} else {
269+
None
270+
}
271+
}
272+
ReadUntil::Any(anys) => anys
273+
.iter()
274+
// Filter matching needles
275+
.filter_map(|any| find(any, buffer, eof))
276+
// Return the left-most match
277+
.min_by(|(start1, end1), (start2, end2)| {
278+
if start1 == start2 {
279+
end1.cmp(end2)
280+
} else {
281+
start1.cmp(start2)
282+
}
283+
}),
284+
}
285+
}
286+
287+
#[derive(Debug)]
288+
enum PipeError {
289+
IO(io::Error),
290+
}
291+
292+
#[derive(Debug)]
293+
#[allow(clippy::upper_case_acronyms)]
294+
enum PipedChar {
295+
Char(u8),
296+
EOF,
297+
}
298+
299299
#[cfg(test)]
300300
mod tests {
301301
use super::*;

src/session.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::process::PtyProcess;
55
use crate::reader::{NBReader, Regex};
66
pub use crate::reader::{Options, ReadUntil};
77
use std::fs::File;
8-
use std::io::LineWriter;
98
use std::io::prelude::*;
9+
use std::io::LineWriter;
1010
use std::ops::{Deref, DerefMut};
1111
use std::process::Command;
1212
use tempfile;
@@ -88,11 +88,6 @@ impl<W: Write> StreamSession<W> {
8888
self.reader.try_read()
8989
}
9090

91-
// wrapper around reader::read_until to give more context for errors
92-
fn exp(&mut self, needle: &ReadUntil) -> Result<(String, String), Error> {
93-
self.reader.read_until(needle)
94-
}
95-
9691
/// Wait until we see EOF (i.e. child process has terminated)
9792
/// Return all the yet unread output
9893
pub fn exp_eof(&mut self) -> Result<String, Error> {
@@ -149,6 +144,11 @@ impl<W: Write> StreamSession<W> {
149144
pub fn exp_any(&mut self, needles: Vec<ReadUntil>) -> Result<(String, String), Error> {
150145
self.exp(&ReadUntil::Any(needles))
151146
}
147+
148+
// wrapper around reader::read_until to give more context for errors
149+
fn exp(&mut self, needle: &ReadUntil) -> Result<(String, String), Error> {
150+
self.reader.read_until(needle)
151+
}
152152
}
153153
/// Interact with a process with read/write/signals, etc.
154154
#[allow(dead_code)]

0 commit comments

Comments
 (0)