zlink_core/connection/
socket.rs

1//! The low-level Socket read and write traits.
2
3use core::future::Future;
4
5/// The socket trait.
6///
7/// This is the trait that needs to be implemented for a type to be used as a socket/transport.
8pub trait Socket: core::fmt::Debug {
9    /// The read half of the socket.
10    type ReadHalf: ReadHalf;
11    /// The write half of the socket.
12    type WriteHalf: WriteHalf;
13
14    /// Split the socket into read and write halves.
15    fn split(self) -> (Self::ReadHalf, Self::WriteHalf);
16}
17
18/// The read half of a socket.
19pub trait ReadHalf: core::fmt::Debug {
20    /// Read from a socket.
21    ///
22    /// On completion, the number of bytes read is returned.
23    ///
24    /// Notes for implementers:
25    ///
26    /// * The future returned by this method must be cancel safe.
27    /// * While there is no explicit `Unpin` bound on the future returned by this method, it is
28    ///   expected that it provides the same guarentees as `Unpin` would require. The reason `Unpin`
29    ///   is not explicitly requied is that it would force boxing (and therefore allocation) on the
30    ///   implemention that use `async fn`, which is undesirable for embedded use cases. See [this
31    ///   issue](https://github.com/rust-lang/rust/issues/82187) for details.
32    fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = crate::Result<usize>>;
33}
34
35/// The write half of a socket.
36pub trait WriteHalf: core::fmt::Debug {
37    /// Write to the socket.
38    ///
39    /// The returned future has the same requirements as that of [`ReadHalf::read`].
40    fn write(&mut self, buf: &[u8]) -> impl Future<Output = crate::Result<()>>;
41}
42
43/// Documentation-only socket implementations for doc tests.
44///
45/// These types exist only to make doc tests compile and should never be used in real code.
46#[doc(hidden)]
47pub mod impl_for_doc {
48
49    /// A mock socket for documentation examples.
50    #[derive(Debug)]
51    pub struct Socket;
52
53    impl super::Socket for Socket {
54        type ReadHalf = ReadHalf;
55        type WriteHalf = WriteHalf;
56
57        fn split(self) -> (Self::ReadHalf, Self::WriteHalf) {
58            (ReadHalf, WriteHalf)
59        }
60    }
61
62    /// A mock read half for documentation examples.
63    #[derive(Debug)]
64    pub struct ReadHalf;
65
66    impl super::ReadHalf for ReadHalf {
67        async fn read(&mut self, _buf: &mut [u8]) -> crate::Result<usize> {
68            unreachable!("This is only for doc tests")
69        }
70    }
71
72    /// A mock write half for documentation examples.
73    #[derive(Debug)]
74    pub struct WriteHalf;
75
76    impl super::WriteHalf for WriteHalf {
77        async fn write(&mut self, _buf: &[u8]) -> crate::Result<()> {
78            unreachable!("This is only for doc tests")
79        }
80    }
81}