1- use std:: io:: Read ;
1+ use std:: io:: { BufRead , BufReader , Read } ;
22
33pub use portable_pty:: CommandBuilder ;
44use 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.
2727pub 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
4447impl 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}
0 commit comments