1#![deny(clippy::pedantic)]
3#![allow(
4 clippy::missing_fields_in_debug,
5 clippy::missing_errors_doc,
6 clippy::missing_panics_doc,
7 clippy::must_use_candidate
8)]
9use std::io::{Error as IoError, Result as IoResult};
10use std::{any::Any, any::TypeId, fmt, task::Poll};
11
12pub mod cfg;
13pub mod testing;
14pub mod types;
15
16mod buf;
17mod ctx;
18mod filter;
19mod filterptr;
20mod flags;
21mod framed;
22mod io;
23mod ioref;
24mod macros;
25mod ops;
26mod seal;
27mod utils;
28
29use ntex_codec::Decoder;
30
31pub use self::buf::{FilterBuf, FilterCtx};
32pub use self::cfg::IoConfig;
33pub use self::ctx::IoContext;
34pub use self::filter::{Base, Filter, Layer};
35pub use self::framed::Framed;
36pub use self::io::{Io, IoRef, OnDisconnect};
37pub use self::ops::{Id, TimerHandle};
38pub use self::seal::{IoBoxed, Sealed};
39pub use self::utils::{Decoded, seal};
40
41#[doc(hidden)]
42pub use self::flags::Flags;
43
44#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
46pub enum Readiness {
47 Ready,
49 Shutdown,
51 Terminate,
53}
54
55impl Readiness {
56 pub fn merge(val1: Poll<Readiness>, val2: Poll<Readiness>) -> Poll<Readiness> {
58 match val1 {
59 Poll::Pending => Poll::Pending,
60 Poll::Ready(Readiness::Ready) => val2,
61 Poll::Ready(Readiness::Terminate) => Poll::Ready(Readiness::Terminate),
62 Poll::Ready(Readiness::Shutdown) => {
63 if val2 == Poll::Ready(Readiness::Terminate) {
64 Poll::Ready(Readiness::Terminate)
65 } else {
66 Poll::Ready(Readiness::Shutdown)
67 }
68 }
69 }
70 }
71}
72
73#[allow(unused_variables)]
74pub trait FilterLayer: fmt::Debug + 'static {
75 fn query(&self, id: TypeId) -> Option<Box<dyn Any>> {
77 None
78 }
79
80 fn process_read_buf(&self, buf: &FilterBuf<'_>) -> IoResult<()>;
82
83 fn process_write_buf(&self, buf: &FilterBuf<'_>) -> IoResult<()>;
85
86 fn shutdown(&self, buf: &FilterBuf<'_>) -> IoResult<Poll<()>> {
88 Ok(Poll::Ready(()))
89 }
90}
91
92pub trait IoStream {
93 fn start(self, _: IoContext) -> Box<dyn Handle>;
94}
95
96#[doc(hidden)]
97pub trait IoCallbacks {
99 fn before_processing(&self, io: &IoRef);
101
102 fn after_processing(&self, io: &IoRef);
104}
105
106pub trait Handle {
107 fn query(&self, _: TypeId) -> Option<Box<dyn Any>> {
108 None
109 }
110
111 #[inline]
112 fn write(&self, _: &IoContext) {}
114
115 #[inline]
116 fn notify(&self, ctx: &IoContext) {
118 ctx.notify();
119 }
120}
121
122#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
124pub enum IoTaskStatus {
125 Io,
127 Pause,
129 Stop,
131}
132
133#[derive(Debug)]
135pub enum IoStatusUpdate {
136 KeepAlive,
138 WriteBackpressure,
140 PeerGone(Option<IoError>),
142}
143
144pub enum RecvError<U: Decoder> {
146 KeepAlive,
148 WriteBackpressure,
150 Decoder(U::Error),
152 PeerGone(Option<IoError>),
154}
155
156impl<U> fmt::Debug for RecvError<U>
157where
158 U: Decoder,
159 <U as Decoder>::Error: fmt::Debug,
160{
161 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
162 match *self {
163 RecvError::KeepAlive => {
164 write!(fmt, "RecvError::KeepAlive")
165 }
166 RecvError::WriteBackpressure => {
167 write!(fmt, "RecvError::WriteBackpressure")
168 }
169 RecvError::Decoder(ref e) => {
170 write!(fmt, "RecvError::Decoder({e:?})")
171 }
172 RecvError::PeerGone(ref e) => {
173 write!(fmt, "RecvError::PeerGone({e:?})")
174 }
175 }
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182 use ntex_codec::BytesCodec;
183 use std::io;
184
185 #[test]
186 fn test_fmt() {
187 assert!(format!("{:?}", IoStatusUpdate::KeepAlive).contains("KeepAlive"));
188 assert!(format!("{:?}", RecvError::<BytesCodec>::KeepAlive).contains("KeepAlive"));
189 assert!(
190 format!("{:?}", RecvError::<BytesCodec>::WriteBackpressure)
191 .contains("WriteBackpressure")
192 );
193 assert!(
194 format!(
195 "{:?}",
196 RecvError::<BytesCodec>::Decoder(io::Error::other("err"))
197 )
198 .contains("RecvError::Decoder")
199 );
200 assert!(
201 format!(
202 "{:?}",
203 RecvError::<BytesCodec>::PeerGone(Some(io::Error::other("err")))
204 )
205 .contains("RecvError::PeerGone")
206 );
207 }
208}