Skip to content

Commit a687364

Browse files
committed
Simplify milestone read_until buffer handling
1 parent d9a2e1b commit a687364

2 files changed

Lines changed: 15 additions & 44 deletions

File tree

  • crates
    • pty_terminal_test_client/src
    • pty_terminal_test/src

crates/pty_terminal_test/src/lib.rs

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::io::Read;
1+
use std::io::{BufRead, BufReader, Read};
22

33
pub use portable_pty::CommandBuilder;
44
use pty_terminal::terminal::{PtyReader, Terminal};
@@ -25,7 +25,7 @@ pub struct TestTerminal {
2525

2626
/// The read half of a test terminal, wrapping [`PtyReader`] with milestone support.
2727
pub struct Reader {
28-
pty: PtyReader,
28+
pty: BufReader<PtyReader>,
2929
child_handle: ChildHandle,
3030
}
3131

@@ -37,13 +37,16 @@ impl TestTerminal {
3737
/// Returns an error if the PTY cannot be opened or the command fails to spawn.
3838
pub fn spawn(size: ScreenSize, cmd: CommandBuilder) -> anyhow::Result<Self> {
3939
let Terminal { pty_reader, pty_writer, child_handle } = Terminal::spawn(size, cmd)?;
40-
Ok(Self { writer: pty_writer, reader: Reader { pty: pty_reader, child_handle } })
40+
Ok(Self {
41+
writer: pty_writer,
42+
reader: Reader { pty: BufReader::new(pty_reader), child_handle },
43+
})
4144
}
4245
}
4346

4447
impl Reader {
4548
fn sanitized_screen_contents(&self) -> String {
46-
self.pty.screen_contents().replace(MILESTONE_FENCE_CHAR, "")
49+
self.pty.get_ref().screen_contents().replace(MILESTONE_FENCE_CHAR, "")
4750
}
4851

4952
/// Reads from the PTY until a milestone with the given name is encountered.
@@ -69,39 +72,16 @@ impl Reader {
6972
milestone.extend_from_slice(name.as_bytes());
7073
milestone.push(0x07); // BEL terminator
7174

72-
let fence: &[u8] = pty_terminal_test_client::MILESTONE_FENCE;
73-
74-
let mut buf = [0u8; 4096];
75-
let mut milestone_match = 0usize;
76-
let mut found_milestone = false;
77-
let mut fence_match = 0usize;
75+
let fence = pty_terminal_test_client::MILESTONE_FENCE;
76+
let fence_last_byte = fence[fence.len() - 1];
77+
let mut buf = Vec::new();
7878

7979
loop {
80-
let n = self.pty.read(&mut buf).expect("PTY read failed");
80+
let n = self.pty.read_until(fence_last_byte, &mut buf).expect("PTY read failed");
8181
assert!(n > 0, "EOF reached before milestone '{name}'");
8282

83-
for byte in &buf[..n] {
84-
if !found_milestone {
85-
if *byte == milestone[milestone_match] {
86-
milestone_match += 1;
87-
if milestone_match == milestone.len() {
88-
found_milestone = true;
89-
fence_match = 0;
90-
}
91-
} else {
92-
milestone_match = usize::from(*byte == milestone[0]);
93-
}
94-
continue;
95-
}
96-
97-
if *byte == fence[fence_match] {
98-
fence_match += 1;
99-
if fence_match == fence.len() {
100-
return self.sanitized_screen_contents();
101-
}
102-
} else {
103-
fence_match = usize::from(*byte == fence[0]);
104-
}
83+
if buf.ends_with(fence) && buf.windows(milestone.len()).any(|w| w == milestone) {
84+
return self.sanitized_screen_contents();
10585
}
10686
}
10787
}
@@ -116,14 +96,4 @@ impl Reader {
11696
self.pty.read_to_end(&mut discard).expect("PTY read_to_end failed");
11797
self.child_handle.wait()
11898
}
119-
120-
/// Returns the current terminal screen contents.
121-
///
122-
/// # Panics
123-
///
124-
/// Panics if the parser lock is poisoned.
125-
#[must_use]
126-
pub fn screen_contents(&self) -> String {
127-
self.sanitized_screen_contents()
128-
}
12999
}

crates/pty_terminal_test_client/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ pub const MILESTONE_FENCE: &[u8] = "\u{200b}".as_bytes();
2323
/// Each milestone also appends a non-visual zero-width-space fence (`U+200B`,
2424
/// UTF-8 `E2 80 8B`). This keeps a uniform protocol across platforms. On
2525
/// Windows, waiting for this rendered character after the OSC confirms prior
26-
/// rendered output has been consumed.
26+
/// rendered output has been consumed. This marker was also confirmed not to
27+
/// advance cursor position on both macOS and Windows in PTY probe runs.
2728
///
2829
/// When the `testing` feature is disabled, this is a no-op.
2930
///

0 commit comments

Comments
 (0)