@@ -17,7 +17,7 @@ pub struct Terminal {
1717 reader : Box < dyn Read + Send > ,
1818 writer : Arc < Mutex < Option < Box < dyn Write + Send > > > > ,
1919
20- /// Unprocessed data buffer for read_until
20+ /// Unprocessed data buffer for ` read_until`
2121 read_until_buffer : Vec < u8 > ,
2222
2323 /// Exit status from the child process, set once by background thread
@@ -54,6 +54,15 @@ impl vt100::Callbacks for Vt100Callbacks {
5454}
5555
5656impl Terminal {
57+ /// Spawns a new child process in a headless terminal with the given size and command.
58+ ///
59+ /// # Errors
60+ ///
61+ /// Returns an error if the PTY cannot be opened or the command fails to spawn.
62+ ///
63+ /// # Panics
64+ ///
65+ /// Panics if the writer lock is poisoned when the background thread closes it.
5766 pub fn spawn ( size : ScreenSize , cmd : CommandBuilder ) -> anyhow:: Result < Self > {
5867 let pty_pair = portable_pty:: native_pty_system ( ) . openpty ( portable_pty:: PtySize {
5968 rows : size. rows ,
@@ -106,6 +115,10 @@ impl Terminal {
106115 /// However, `screen_contents` will reflect all data, including subsequent occurrences,
107116 /// even before they are consumed by `read_until`. It is designed this way because the
108117 /// screen must always have latest data for proper query responses.
118+ ///
119+ /// # Errors
120+ ///
121+ /// Returns an error if the expected string is not found before EOF or if reading fails.
109122 pub fn read_until ( & mut self , expected : & str ) -> anyhow:: Result < ( ) > {
110123 let expected_bytes = expected. as_bytes ( ) ;
111124
@@ -131,7 +144,7 @@ impl Terminal {
131144
132145 if n == 0 {
133146 // EOF - expected string not found
134- return Err ( anyhow:: anyhow!( "Expected string not found: {}" , expected ) ) ;
147+ return Err ( anyhow:: anyhow!( "Expected string not found: {expected}" ) ) ;
135148 }
136149
137150 let data = & buf[ ..n] ;
@@ -142,6 +155,11 @@ impl Terminal {
142155 }
143156 }
144157
158+ /// Kills the child process.
159+ ///
160+ /// # Errors
161+ ///
162+ /// Returns an error if the child process cannot be killed.
145163 pub fn kill ( & mut self ) -> anyhow:: Result < ( ) > {
146164 self . child_killer . kill ( ) ?;
147165 Ok ( ( ) )
@@ -176,10 +194,15 @@ impl Terminal {
176194 Ok ( status)
177195 }
178196
179- pub fn write ( & mut self , data : & [ u8 ] ) -> anyhow:: Result < ( ) > {
197+ /// Writes data to the child process's stdin.
198+ ///
199+ /// # Errors
200+ ///
201+ /// Returns an error if the child process has already exited or if writing fails.
202+ pub fn write ( & self , data : & [ u8 ] ) -> anyhow:: Result < ( ) > {
180203 // On Windows ConPTY, convert LF to CRLF for proper line handling
181204 #[ cfg( target_os = "windows" ) ]
182- let data_to_write : Vec < u8 > = {
205+ let converted : Vec < u8 > = {
183206 let mut result = Vec :: new ( ) ;
184207 for & byte in data {
185208 if byte == b'\n' {
@@ -192,16 +215,19 @@ impl Terminal {
192215 result
193216 } ;
194217
218+ #[ cfg( target_os = "windows" ) ]
219+ let data_to_write: & [ u8 ] = & converted;
220+
195221 #[ cfg( not( target_os = "windows" ) ) ]
196- let data_to_write = data;
222+ let data_to_write: & [ u8 ] = data;
197223
198224 let mut writer_guard = self
199225 . writer
200226 . lock ( )
201- . map_err ( |e| anyhow:: anyhow!( "Failed to acquire writer lock: {}" , e ) ) ?;
227+ . map_err ( |e| anyhow:: anyhow!( "Failed to acquire writer lock: {e}" ) ) ?;
202228
203229 if let Some ( writer) = writer_guard. as_mut ( ) {
204- writer. write_all ( & data_to_write) ?;
230+ writer. write_all ( data_to_write) ?;
205231 writer. flush ( ) ?;
206232 Ok ( ( ) )
207233 } else {
@@ -216,16 +242,22 @@ impl Terminal {
216242 /// Returns an error if:
217243 /// - The child process has already exited
218244 /// - Writing to the PTY fails
219- pub fn send_ctrl_c ( & mut self ) -> anyhow:: Result < ( ) > {
245+ pub fn send_ctrl_c ( & self ) -> anyhow:: Result < ( ) > {
220246 // ASCII 0x03 (ETX) is Ctrl+C
221247 // Both Unix PTY and Windows ConPTY interpret this and signal the child
222248 self . write ( & [ 0x03 ] )
223249 }
224250
251+ #[ must_use]
225252 pub fn screen_contents ( & self ) -> String {
226253 self . parser . screen ( ) . contents ( )
227254 }
228255
256+ /// Resizes the terminal to the given size.
257+ ///
258+ /// # Errors
259+ ///
260+ /// Returns an error if the PTY cannot be resized.
229261 pub fn resize ( & mut self , size : ScreenSize ) -> anyhow:: Result < ( ) > {
230262 // Resize the underlying PTY via portable-pty's MasterPty::resize
231263 self . pty_pair . master . resize ( portable_pty:: PtySize {
0 commit comments