distant_net/server/builder/
tcp.rs1use std::io;
2use std::net::IpAddr;
3
4use distant_auth::Verifier;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8use crate::common::{PortRange, TcpListener, Version};
9use crate::server::{Server, ServerConfig, ServerHandler, TcpServerRef};
10
11pub struct TcpServerBuilder<T>(Server<T>);
12
13impl<T> Server<T> {
14 pub fn into_tcp_builder(self) -> TcpServerBuilder<T> {
16 TcpServerBuilder(self)
17 }
18}
19
20impl Default for TcpServerBuilder<()> {
21 fn default() -> Self {
22 Self(Server::new())
23 }
24}
25
26impl<T> TcpServerBuilder<T> {
27 pub fn config(self, config: ServerConfig) -> Self {
28 Self(self.0.config(config))
29 }
30
31 pub fn handler<U>(self, handler: U) -> TcpServerBuilder<U> {
32 TcpServerBuilder(self.0.handler(handler))
33 }
34
35 pub fn verifier(self, verifier: Verifier) -> Self {
36 Self(self.0.verifier(verifier))
37 }
38
39 pub fn version(self, version: Version) -> Self {
40 Self(self.0.version(version))
41 }
42}
43
44impl<T> TcpServerBuilder<T>
45where
46 T: ServerHandler + Sync + 'static,
47 T::Request: DeserializeOwned + Send + Sync + 'static,
48 T::Response: Serialize + Send + 'static,
49{
50 pub async fn start<P>(self, addr: IpAddr, port: P) -> io::Result<TcpServerRef>
51 where
52 P: Into<PortRange> + Send,
53 {
54 let listener = TcpListener::bind(addr, port).await?;
55 let port = listener.port();
56 let inner = self.0.start(listener)?;
57 Ok(TcpServerRef { addr, port, inner })
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use std::net::{Ipv6Addr, SocketAddr};
64
65 use async_trait::async_trait;
66 use distant_auth::DummyAuthHandler;
67 use test_log::test;
68
69 use super::*;
70 use crate::client::Client;
71 use crate::common::Request;
72 use crate::server::RequestCtx;
73
74 pub struct TestServerHandler;
75
76 #[async_trait]
77 impl ServerHandler for TestServerHandler {
78 type Request = String;
79 type Response = String;
80
81 async fn on_request(&self, ctx: RequestCtx<Self::Request, Self::Response>) {
82 ctx.reply.send(ctx.request.payload.to_string()).unwrap();
84 }
85 }
86
87 #[test(tokio::test)]
88 async fn should_invoke_handler_upon_receiving_a_request() {
89 let server = TcpServerBuilder::default()
90 .handler(TestServerHandler)
91 .verifier(Verifier::none())
92 .start(IpAddr::V6(Ipv6Addr::LOCALHOST), 0)
93 .await
94 .expect("Failed to start TCP server");
95
96 let mut client: Client<String, String> =
97 Client::tcp(SocketAddr::from((server.ip_addr(), server.port())))
98 .auth_handler(DummyAuthHandler)
99 .connect()
100 .await
101 .expect("Client failed to connect");
102
103 let response = client
104 .send(Request::new("hello".to_string()))
105 .await
106 .expect("Failed to send message");
107 assert_eq!(response.payload, "hello");
108 }
109}