distant_net/server/builder/
unix.rs1use std::io;
2use std::path::Path;
3
4use distant_auth::Verifier;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8use crate::common::{UnixSocketListener, Version};
9use crate::server::{Server, ServerConfig, ServerHandler, UnixSocketServerRef};
10
11pub struct UnixSocketServerBuilder<T>(Server<T>);
12
13impl<T> Server<T> {
14 pub fn into_unix_socket_builder(self) -> UnixSocketServerBuilder<T> {
16 UnixSocketServerBuilder(self)
17 }
18}
19
20impl Default for UnixSocketServerBuilder<()> {
21 fn default() -> Self {
22 Self(Server::new())
23 }
24}
25
26impl<T> UnixSocketServerBuilder<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) -> UnixSocketServerBuilder<U> {
32 UnixSocketServerBuilder(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> UnixSocketServerBuilder<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, path: P) -> io::Result<UnixSocketServerRef>
51 where
52 P: AsRef<Path> + Send,
53 {
54 let path = path.as_ref();
55 let listener = UnixSocketListener::bind(path).await?;
56 let path = listener.path().to_path_buf();
57 let inner = self.0.start(listener)?;
58 Ok(UnixSocketServerRef { path, inner })
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use async_trait::async_trait;
65 use distant_auth::DummyAuthHandler;
66 use tempfile::NamedTempFile;
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 path = NamedTempFile::new()
91 .expect("Failed to create socket file")
92 .path()
93 .to_path_buf();
94
95 let server = UnixSocketServerBuilder::default()
96 .handler(TestServerHandler)
97 .verifier(Verifier::none())
98 .start(path)
99 .await
100 .expect("Failed to start Unix socket server");
101
102 let mut client: Client<String, String> = Client::unix_socket(server.path())
103 .auth_handler(DummyAuthHandler)
104 .connect()
105 .await
106 .expect("Client failed to connect");
107
108 let response = client
109 .send(Request::new("hello".to_string()))
110 .await
111 .expect("Failed to send message");
112 assert_eq!(response.payload, "hello");
113 }
114}