monolake_services/tcp/
echo.rs

1use std::{convert::Infallible, io};
2
3use monoio::io::{AsyncReadRent, AsyncWriteRent, AsyncWriteRentExt};
4use service_async::{
5    layer::{layer_fn, FactoryLayer},
6    AsyncMakeService, MakeService, Param, Service,
7};
8
9pub struct EchoService {
10    buffer_size: usize,
11}
12
13impl<S> Service<S> for EchoService
14where
15    S: AsyncReadRent + AsyncWriteRent,
16{
17    type Response = ();
18    type Error = io::Error;
19
20    async fn call(&self, mut io: S) -> Result<Self::Response, Self::Error> {
21        let mut buffer = Vec::with_capacity(self.buffer_size);
22        loop {
23            let (mut r, buf) = io.read(buffer).await;
24            if r? == 0 {
25                break;
26            }
27            (r, buffer) = io.write_all(buf).await;
28            r?;
29        }
30        tracing::info!("tcp relay finished successfully");
31        Ok(())
32    }
33}
34
35impl MakeService for EchoService {
36    type Service = Self;
37    type Error = Infallible;
38
39    fn make_via_ref(&self, _old: Option<&Self::Service>) -> Result<Self::Service, Self::Error> {
40        Ok(EchoService {
41            buffer_size: self.buffer_size,
42        })
43    }
44}
45
46impl AsyncMakeService for EchoService {
47    type Service = Self;
48    type Error = Infallible;
49
50    async fn make_via_ref(
51        &self,
52        _old: Option<&Self::Service>,
53    ) -> Result<Self::Service, Self::Error> {
54        Ok(EchoService {
55            buffer_size: self.buffer_size,
56        })
57    }
58}
59
60#[derive(Debug, Clone)]
61pub struct EchoConfig {
62    pub buffer_size: usize,
63}
64
65impl Default for EchoConfig {
66    fn default() -> Self {
67        Self { buffer_size: 4096 }
68    }
69}
70
71impl EchoService {
72    pub fn layer<C>() -> impl FactoryLayer<C, (), Factory = Self>
73    where
74        C: Param<EchoConfig>,
75    {
76        layer_fn(|c: &C, ()| Self {
77            buffer_size: c.param().buffer_size,
78        })
79    }
80}