gdbstub/conn/mod.rs
1//! Traits to perform in-order, serial, byte-wise I/O.
2
3mod impls;
4
5/// A trait to perform in-order, serial, byte-wise I/O.
6///
7/// When the `std` feature is enabled, this trait is automatically implemented
8/// for [`TcpStream`](std::net::TcpStream) and
9/// [`UnixStream`](std::os::unix::net::UnixStream) (on unix systems).
10pub trait Connection {
11 /// Transport-specific error type.
12 type Error;
13
14 /// Write a single byte.
15 fn write(&mut self, byte: u8) -> Result<(), Self::Error>;
16
17 /// Write the entire buffer, blocking until complete.
18 ///
19 /// This method's default implementation calls `self.write()` on each byte
20 /// in the buffer. This can be quite inefficient, so if a more efficient
21 /// implementation exists (such as calling `write_all()` on an underlying
22 /// `std::io::Write` object), this method should be overwritten.
23 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
24 for b in buf {
25 self.write(*b)?;
26 }
27 Ok(())
28 }
29
30 /// Flush this Connection, ensuring that all intermediately buffered
31 /// contents reach their destination.
32 ///
33 /// _Note:_ Not all `Connection`s have internal buffering (e.g: writing data
34 /// to a UART TX register with FIFOs disabled). In these cases, it's fine to
35 /// simply return `Ok(())`.
36 fn flush(&mut self) -> Result<(), Self::Error>;
37
38 /// Called at the start of a debugging session _before_ any GDB packets have
39 /// been sent/received.
40 ///
41 /// This method's default implementation is a no-op.
42 ///
43 /// # Example
44 ///
45 /// The `on_session_start` implementation for `TcpStream` ensures that
46 /// [`set_nodelay(true)`](std::net::TcpStream::set_nodelay)
47 /// is called. The GDB remote serial protocol requires sending/receiving
48 /// many small packets, so forgetting to enable `TCP_NODELAY` can result in
49 /// a massively degraded debugging experience.
50 fn on_session_start(&mut self) -> Result<(), Self::Error> {
51 Ok(())
52 }
53}
54
55/// Extends [`Connection`] with `read` and `peek` methods.
56///
57/// This trait is used as part of `gdbstub`'s quickstart
58/// [`GdbStub::run_blocking`](crate::stub::GdbStub::run_blocking) API.
59///
60/// When the `std` feature is enabled, this trait is automatically implemented
61/// for [`TcpStream`](std::net::TcpStream) and
62/// [`UnixStream`](std::os::unix::net::UnixStream) (on unix systems).
63pub trait ConnectionExt: Connection {
64 /// Read a single byte.
65 fn read(&mut self) -> Result<u8, Self::Error>;
66
67 /// Peek a single byte. This MUST be a **non-blocking** operation, returning
68 /// `None` if no byte is available.
69 ///
70 /// Returns a byte (if one is available) without removing that byte from the
71 /// queue. Subsequent calls to `peek` MUST return the same byte.
72 fn peek(&mut self) -> Result<Option<u8>, Self::Error>;
73}