|
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