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