1use std::{any::Any, any::TypeId, fmt, io, ops, task::Context, task::Poll};
2
3use crate::{Filter, FilterCtx, Io, Readiness};
4
5pub struct Sealed(pub(crate) Box<dyn Filter>);
7
8impl fmt::Debug for Sealed {
9 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10 f.debug_struct("Sealed").finish()
11 }
12}
13
14impl Filter for Sealed {
15 #[inline]
16 fn query(&self, id: TypeId) -> Option<Box<dyn Any>> {
17 self.0.query(id)
18 }
19
20 #[inline]
21 fn process_read_buf(&self, ctx: &mut FilterCtx<'_>) -> io::Result<()> {
22 self.0.process_read_buf(ctx)
23 }
24
25 #[inline]
26 fn process_write_buf(&self, ctx: &mut FilterCtx<'_>) -> io::Result<()> {
27 self.0.process_write_buf(ctx)
28 }
29
30 #[inline]
31 fn shutdown(&self, ctx: &mut FilterCtx<'_>) -> io::Result<Poll<()>> {
32 self.0.shutdown(ctx)
33 }
34
35 #[inline]
36 fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Readiness> {
37 self.0.poll_read_ready(cx)
38 }
39
40 #[inline]
41 fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Readiness> {
42 self.0.poll_write_ready(cx)
43 }
44}
45
46#[derive(Debug)]
47pub struct IoBoxed(Io<Sealed>);
49
50impl IoBoxed {
51 #[inline]
52 #[must_use]
53 pub fn take(&mut self) -> Self {
57 IoBoxed(self.0.take())
58 }
59}
60
61impl<F: Filter> From<Io<F>> for IoBoxed {
62 fn from(io: Io<F>) -> Self {
63 Self(io.seal())
64 }
65}
66
67impl ops::Deref for IoBoxed {
68 type Target = Io<Sealed>;
69
70 #[inline]
71 fn deref(&self) -> &Self::Target {
72 &self.0
73 }
74}
75
76impl From<IoBoxed> for Io<Sealed> {
77 fn from(value: IoBoxed) -> Self {
78 value.0
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use ntex_bytes::Bytes;
85 use ntex_codec::BytesCodec;
86 use ntex_service::{ServiceFactory, cfg::SharedCfg, fn_service};
87
88 use super::*;
89 use crate::{testing::IoTest, utils::seal};
90
91 #[ntex::test]
92 async fn test_seal() {
93 let (client, server) = IoTest::create();
94 client.remote_buffer_cap(1024);
95 client.write("REQ");
96
97 let svc = seal(fn_service(|io: IoBoxed| async move {
98 let t = io.recv(&BytesCodec).await.unwrap().unwrap();
99 assert_eq!(t, b"REQ".as_ref());
100 io.send(Bytes::from_static(b"RES"), &BytesCodec)
101 .await
102 .unwrap();
103 Ok::<_, ()>(())
104 }))
105 .pipeline(())
106 .await
107 .unwrap();
108
109 let srv: Io<Sealed> = Io::new(server, SharedCfg::default()).boxed().into();
110 let _ = svc.call(srv).await;
111
112 let buf = client.read().await.unwrap();
113 assert_eq!(buf, b"RES".as_ref());
114 }
115}