message_io/network/adapter.rs
1use crate::network::transport::{TransportConnect, TransportListen};
2
3use super::remote_addr::{RemoteAddr};
4use super::poll::{Readiness};
5
6use mio::event::{Source};
7
8use std::net::{SocketAddr};
9use std::io::{self};
10
11/// High level trait to represent an adapter for a transport protocol.
12/// The adapter is only used to identify the resources of your adapter.
13pub trait Adapter: Send + Sync {
14 /// Resource type used to identify remote connections and send/receive
15 /// from remote this endpoints (e.g. TcpStream)
16 /// This can be considerered the resource used for client connections.
17 type Remote: Remote;
18
19 /// Resource type used to accept new connections (e.g. TcpListener)
20 /// This can be considerered the resource used for server listenings.
21 type Local: Local<Remote = Self::Remote>;
22}
23
24/// A `Resource` is defined as an object that can return a mutable reference to a [`Source`].
25/// `Source` is the trait that [`mio`] uses to register in the poll in order to wake up
26/// asynchronously from events.
27/// Your [`Remote`] and [`Local`] entities must implement `Resource`.
28pub trait Resource: Send + Sync {
29 /// Returns a mutable reference to the internal `Source`.
30 /// Note: All `mio` network element implements [`Source`], you probably wants to use
31 /// one of them as a base for your non-blocking transport.
32 /// See [`Source`].
33 fn source(&mut self) -> &mut dyn Source;
34}
35
36/// Plain struct used as a returned value of [`Remote::connect_with()`]
37pub struct ConnectionInfo<R: Remote> {
38 /// The new created remote resource
39 pub remote: R,
40
41 /// Local address of the interal resource used.
42 pub local_addr: SocketAddr,
43
44 /// Peer address of the interal resource used.
45 pub peer_addr: SocketAddr,
46}
47
48/// Plain struct used as a returned value of [`Local::listen_with()`]
49pub struct ListeningInfo<L: Local> {
50 /// The new created local resource
51 pub local: L,
52
53 /// Local address generated after perform the listening action.
54 pub local_addr: SocketAddr,
55}
56
57/// The following represents the posible status that [`crate::network::NetworkController::send()`]
58/// call can return.
59/// The library do not encourage to perform the check of this status for each `send()` call,
60/// only in that cases where you need extra information about how the sending method was.
61#[derive(Clone, Copy, PartialEq, Eq, Debug)]
62pub enum SendStatus {
63 /// This status is received when the entire data has been sent.
64 /// It does not guarantees that the packet have been successfully received by the endpoint.
65 /// It means that the correspond adapter has sent the message to the OS without errors.
66 Sent,
67
68 /// This status is received in packet-based protocols where there is a limit in the bytes
69 /// that a packet can have.
70 MaxPacketSizeExceeded,
71
72 /// It means that the message could not be sent by the specified `ResourceId`.
73 /// This implies that a [`crate::network::NetEvent::Disconnected`] has happened or that
74 /// the resource never existed.
75 ResourceNotFound,
76
77 /// The resource can not perform the required send operation.
78 /// Usually this is due because it is performing the handshake.
79 ResourceNotAvailable,
80}
81
82/// Returned as a result of [`Remote::receive()`]
83#[derive(Debug)]
84pub enum ReadStatus {
85 /// This status must be returned if the resource has been disconnected or there was an error.
86 /// The resource will be removed after this call and
87 /// no more [`Remote::receive()`] calls will be produced by this resource.
88 Disconnected,
89
90 /// This status must be returned when a the resource (treated as a non-bloking) would wait for
91 /// process the next event.
92 /// Usually, this status is returned if the resource receives
93 /// a [`std::io::ErrorKind::WouldBlock`].
94 WaitNextEvent,
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub enum PendingStatus {
99 /// The resource is no longer considered as a pending resource.
100 /// It it came from a listener, a [`crate::network::NetEvent::Accepted`] event will be generated.
101 /// It it came from a explicit connection, a [`crate::network::NetEvent::Connected`]
102 /// with its flag to `true` will be generated.
103 /// No more calls to [`Remote::pending()`] will be performed.
104 Ready,
105
106 /// The resource needs more data to be considered as established.
107 Incomplete,
108
109 /// The resource has not be able to perform the connection.
110 /// It it came from a listener, no event will be generated.
111 /// It it came from a explicit connection, a [`crate::network::NetEvent::Connected`]
112 /// with its flag to `false` will be generated.
113 /// No more calls to [`Remote::pending()`] will be performed and the resource will be removed.
114 Disconnected,
115}
116
117/// The resource used to represent a remote.
118/// It usually is a wrapper over a socket/stream.
119pub trait Remote: Resource + Sized {
120 /// Called when the user performs a connection request to an specific remote address.
121 /// The **implementator** is in change of creating the corresponding remote resource.
122 /// The [`TransportConnect`] wraps custom transport options for transports that support it. It
123 /// is guaranteed by the upper level to be of the variant matching the adapter. Therefore other
124 /// variants can be safely ignored.
125 /// The [`RemoteAddr`] contains either a [`SocketAddr`] or a [`url::Url`].
126 /// It is in charge of deciding what to do in both cases.
127 /// It also must return the extracted address as `SocketAddr`.
128 fn connect_with(
129 config: TransportConnect,
130 remote_addr: RemoteAddr,
131 ) -> io::Result<ConnectionInfo<Self>>;
132
133 /// Called when a remote resource received an event.
134 /// The resource must be *ready* to receive this call.
135 /// It means that it has available data to read,
136 /// or there is some connection related issue, as a disconnection.
137 /// The **implementator** is in charge of processing that action and returns a [`ReadStatus`].
138 ///
139 /// The `process_data` function must be called for each data chunk that represents a message.
140 /// This call will produce a [`crate::network::NetEvent::Message`] API event.
141 /// Note that `receive()` could imply more than one call to `read`.
142 /// The implementator must be read all data from the resource.
143 /// For most of the cases it means read until the network resource returns `WouldBlock`.
144 fn receive(&self, process_data: impl FnMut(&[u8])) -> ReadStatus;
145
146 /// Sends raw data from a resource.
147 /// The resource must be *ready* to receive this call.
148 /// The **implementator** is in charge to send the entire `data`.
149 /// The [`SendStatus`] will contain the status of this attempt.
150 fn send(&self, data: &[u8]) -> SendStatus;
151
152 /// Called when a `Remote` is created (explicity of by a listener)
153 /// and it is not consider ready yet.
154 /// A remote resource **is considered ready** when it is totally connected
155 /// and can be used for writing data.
156 /// It implies that the user has received the `Connected` or `Accepted` method for that resource.
157 ///
158 /// This method is in charge to determine if a resource is ready or not.
159 /// No `Connected` or `Accepted` events will be generated until this function return
160 /// `PendingStatus::Ready`.
161 /// The method wil be called several times with different `Readiness` until the **implementator**
162 /// returns a `PendingStatus::Ready` or `PendingStatus::Disconnected`.
163 fn pending(&self, readiness: Readiness) -> PendingStatus;
164
165 /// The resource is available to write.
166 /// It must be *ready* to receive this call.
167 /// Here the **implementator** optionally can try to write any pending data.
168 /// The return value is an identification of the operation result.
169 /// If the method returns `true`, the operation was successful, otherwise, the resource will
170 /// be disconnected and removed.
171 fn ready_to_write(&self) -> bool {
172 true
173 }
174}
175
176/// Used as a parameter callback in [`Local::accept()`]
177pub enum AcceptedType<'a, R> {
178 /// The listener has accepted a remote (`R`) with the specified addr.
179 /// The remote will be registered in order to generate read events. (calls to
180 /// [`Remote::receive()`]).
181 /// A [`crate::network::NetEvent::Accepted`] will be generated once this remote resource
182 /// is considered *ready*.
183 Remote(SocketAddr, R),
184
185 /// The listener has accepted data that can be packed into a message from a specified addr.
186 /// Despite of `Remote`, accept as a `Data` will not register any Remote.
187 /// This will produce a [`crate::network::NetEvent::Message`] event.
188 /// The endpoint of this event will be unique containing the specified addr and the listener
189 /// whom generates it.
190 Data(SocketAddr, &'a [u8]),
191}
192
193/// The resource used to represent a local listener.
194/// It usually is a wrapper over a socket/listener.
195pub trait Local: Resource + Sized {
196 /// The type of the Remote accepted by the [`Self::accept()`] function.
197 /// It must be the same as the adapter's `Remote`.
198 type Remote: Remote;
199
200 /// Called when the user performs a listening request from an specific address.
201 /// The **implementator** is in change of creating the corresponding local resource.
202 /// It also must returned the listening address since it could not be the same as param `addr`
203 /// (e.g. listening from port `0`).
204 /// The [`TransportListen`] wraps custom transport options for transports that support it. It
205 /// is guaranteed by the upper level to be of the variant matching the adapter. Therefore other
206 /// variants can be safely ignored.
207 fn listen_with(config: TransportListen, addr: SocketAddr) -> io::Result<ListeningInfo<Self>>;
208
209 /// Called when a local resource received an event.
210 /// It means that some resource have tried to connect.
211 /// The **implementator** is in charge of accepting this connection.
212 /// The `accept_remote` must be called for each accept request in the local resource.
213 /// Note that an accept event could imply to process more than one remote.
214 /// This function is called when the local resource has one or more pending connections.
215 /// The **implementator** must process all these pending connections in this call.
216 /// For most of the cases it means accept connections until the network
217 /// resource returns `WouldBlock`.
218 fn accept(&self, accept_remote: impl FnMut(AcceptedType<'_, Self::Remote>));
219
220 /// Sends a raw data from a resource.
221 /// Similar to [`Remote::send()`] but the resource that sends the data is a `Local`.
222 /// This behaviour usually happens when the transport to implement is not connection oriented.
223 ///
224 /// The **implementator** must **only** implement this function if the local resource can
225 /// also send data.
226 fn send_to(&self, _addr: SocketAddr, _data: &[u8]) -> SendStatus {
227 panic!("Adapter not configured to send messages directly from the local resource")
228 }
229}