|
1 | 1 | use core::future::Future;
|
2 | 2 | use no_std_net::SocketAddr;
|
3 | 3 |
|
4 |
| -/// This trait is implemented by TCP/IP stacks. You could, for example, have an implementation |
5 |
| -/// which knows how to send AT commands to an ESP8266 WiFi module. You could have another implementation |
6 |
| -/// which knows how to driver the Rust Standard Library's `std::net` module. Given this trait, you can |
7 |
| -/// write a portable HTTP client which can work with either implementation. |
8 |
| -pub trait TcpClientStack { |
9 |
| - /// The type returned when we create a new TCP socket |
10 |
| - type TcpSocket; |
11 |
| - /// The type returned when we have an error |
12 |
| - type Error: core::fmt::Debug; |
13 |
| - |
14 |
| - /// Future returned by `socket` function. |
15 |
| - type SocketFuture<'m>: Future<Output = Result<Self::TcpSocket, Self::Error>> + 'm |
16 |
| - where |
17 |
| - Self: 'm; |
18 |
| - |
19 |
| - /// Open a socket for usage as a TCP client. |
20 |
| - /// |
21 |
| - /// The socket must be connected before it can be used. |
22 |
| - /// |
23 |
| - /// Returns `Ok(socket)` if the socket was successfully created. |
24 |
| - fn socket<'m>(&'m mut self) -> Self::SocketFuture<'m>; |
25 |
| - |
26 |
| - /// Future returned by `connect` function. |
27 |
| - type ConnectFuture<'m>: Future<Output = Result<(), Self::Error>> + 'm |
28 |
| - where |
29 |
| - Self: 'm; |
30 |
| - |
31 |
| - /// Connect to the given remote host and port. |
32 |
| - /// |
33 |
| - /// Returns `Ok` if the connection was successful. |
34 |
| - fn connect<'m>( |
35 |
| - &'m mut self, |
36 |
| - socket: &'m mut Self::TcpSocket, |
37 |
| - remote: SocketAddr, |
38 |
| - ) -> Self::ConnectFuture<'m>; |
39 |
| - |
40 |
| - /// Future returned by `is_connected` function. |
41 |
| - type IsConnectedFuture<'m>: Future<Output = Result<bool, Self::Error>> + 'm |
42 |
| - where |
43 |
| - Self: 'm; |
44 |
| - |
45 |
| - /// Check if this socket is connected |
46 |
| - fn is_connected<'m>(&'m mut self, socket: &'m Self::TcpSocket) -> Self::IsConnectedFuture<'m>; |
47 |
| - |
48 |
| - /// Future returned by `send` function. |
49 |
| - type SendFuture<'m>: Future<Output = Result<usize, Self::Error>> + 'm |
50 |
| - where |
51 |
| - Self: 'm; |
52 |
| - |
53 |
| - /// Write to the stream. |
54 |
| - /// |
55 |
| - /// Returns the number of bytes written (which may be less than `buffer.len()`) or an error. |
56 |
| - fn send<'m>( |
57 |
| - &'m mut self, |
58 |
| - socket: &'m mut Self::TcpSocket, |
59 |
| - buffer: &'m [u8], |
60 |
| - ) -> Self::SendFuture<'m>; |
61 |
| - |
62 |
| - /// Future returned by `receive` function. |
63 |
| - type ReceiveFuture<'m>: Future<Output = Result<usize, Self::Error>> + 'm |
64 |
| - where |
65 |
| - Self: 'm; |
66 |
| - |
67 |
| - /// Receive data from the stream. |
68 |
| - /// |
69 |
| - /// Returns `Ok(n)`, which means `n` bytes of data have been received and |
70 |
| - /// they have been placed in `&buffer[0..n]`, or an error. |
71 |
| - fn receive<'m>( |
72 |
| - &'m mut self, |
73 |
| - socket: &'m mut Self::TcpSocket, |
74 |
| - buffer: &'m mut [u8], |
75 |
| - ) -> Self::ReceiveFuture<'m>; |
76 |
| - |
77 |
| - /// Future returned by `close` function. |
78 |
| - type CloseFuture<'m>: Future<Output = Result<(), Self::Error>> + 'm |
79 |
| - where |
80 |
| - Self: 'm; |
81 |
| - |
82 |
| - /// Close an existing TCP socket. |
83 |
| - fn close<'m>(&'m mut self, socket: Self::TcpSocket) -> Self::CloseFuture<'m>; |
84 |
| -} |
85 |
| - |
86 |
| -/// This trait is implemented by TCP/IP stacks that expose TCP server functionality. TCP servers |
87 |
| -/// may listen for connection requests to establish multiple unique TCP connections with various |
88 |
| -/// clients. |
89 |
| -pub trait TcpFullStack: TcpClientStack { |
90 |
| - /// Future returned by `bind` function. |
91 |
| - type BindFuture<'m>: Future<Output = Result<(), Self::Error>> + 'm |
92 |
| - where |
93 |
| - Self: 'm; |
94 |
| - /// Create a new TCP socket and bind it to the specified local port. |
95 |
| - /// |
96 |
| - /// Returns `Ok` when a socket is successfully bound to the specified local port. Otherwise, an |
97 |
| - /// `Err(e)` variant is returned. |
98 |
| - fn bind<'m>( |
99 |
| - &'m mut self, |
100 |
| - socket: &'m mut Self::TcpSocket, |
101 |
| - local_port: u16, |
102 |
| - ) -> Self::BindFuture<'m>; |
103 |
| - |
104 |
| - /// Future returned by `listen` function. |
105 |
| - type ListenFuture<'m>: Future<Output = Result<(), Self::Error>> + 'm |
106 |
| - where |
107 |
| - Self: 'm; |
108 |
| - |
109 |
| - /// Begin listening for connection requests on a previously-bound socket. |
110 |
| - /// |
111 |
| - /// Returns `Ok` if the socket was successfully transitioned to the listening state. Otherwise, |
112 |
| - /// an `Err(e)` variant is returned. |
113 |
| - fn listen<'m>(&'m mut self, socket: &'m mut Self::TcpSocket) -> Self::ListenFuture<'m>; |
114 |
| - |
115 |
| - /// Future returned by `accept` function. |
116 |
| - type AcceptFuture<'m>: Future<Output = Result<(Self::TcpSocket, SocketAddr), Self::Error>> + 'm |
117 |
| - where |
118 |
| - Self: 'm; |
119 |
| - |
120 |
| - /// Accept an active connection request on a listening socket. |
121 |
| - /// |
122 |
| - /// Returns `Ok(connection)` if a new connection was created. If no pending connections are |
123 |
| - /// available, this function should return [`nb::Error::WouldBlock`]. |
124 |
| - fn accept<'m>(&'m mut self, socket: &'m mut Self::TcpSocket) -> Self::AcceptFuture<'m>; |
125 |
| -} |
126 |
| - |
127 |
| -impl<T: TcpClientStack> TcpClientStack for &mut T { |
128 |
| - type Error = T::Error; |
129 |
| - type TcpSocket = T::TcpSocket; |
130 |
| - |
131 |
| - type SocketFuture<'m> = T::SocketFuture<'m> where Self: 'm; |
132 |
| - fn socket<'m>(&'m mut self) -> Self::SocketFuture<'m> { |
133 |
| - T::socket(self) |
134 |
| - } |
135 |
| - |
136 |
| - type ConnectFuture<'m> = T::ConnectFuture<'m> where Self: 'm; |
137 |
| - fn connect<'m>( |
138 |
| - &'m mut self, |
139 |
| - socket: &'m mut Self::TcpSocket, |
140 |
| - remote: SocketAddr, |
141 |
| - ) -> Self::ConnectFuture<'m> { |
142 |
| - T::connect(self, socket, remote) |
143 |
| - } |
144 |
| - |
145 |
| - type IsConnectedFuture<'m> = T::IsConnectedFuture<'m> where Self: 'm; |
146 |
| - fn is_connected<'m>(&'m mut self, socket: &'m Self::TcpSocket) -> Self::IsConnectedFuture<'m> { |
147 |
| - T::is_connected(self, socket) |
148 |
| - } |
149 |
| - |
150 |
| - type SendFuture<'m> = T::SendFuture<'m> where Self: 'm; |
151 |
| - fn send<'m>( |
152 |
| - &'m mut self, |
153 |
| - socket: &'m mut Self::TcpSocket, |
154 |
| - buffer: &'m [u8], |
155 |
| - ) -> Self::SendFuture<'m> { |
156 |
| - T::send(self, socket, buffer) |
157 |
| - } |
158 |
| - |
159 |
| - type ReceiveFuture<'m> = T::ReceiveFuture<'m> where Self: 'm; |
160 |
| - fn receive<'m>( |
161 |
| - &'m mut self, |
162 |
| - socket: &'m mut Self::TcpSocket, |
163 |
| - buffer: &'m mut [u8], |
164 |
| - ) -> Self::ReceiveFuture<'m> { |
165 |
| - T::receive(self, socket, buffer) |
166 |
| - } |
167 |
| - |
168 |
| - type CloseFuture<'m> = T::CloseFuture<'m> where Self: 'm; |
169 |
| - fn close<'m>(&'m mut self, socket: Self::TcpSocket) -> Self::CloseFuture<'m> { |
170 |
| - T::close(self, socket) |
171 |
| - } |
172 |
| -} |
173 |
| - |
174 | 4 | /// This trait is implemented by TCP/IP stacks. The trait allows the underlying driver to
|
175 | 5 | /// construct multiple connections that implement the I/O traits from embedded-io.
|
176 | 6 | ///
|
|
0 commit comments