distant_net/server/builder/
windows.rs1use std::ffi::{OsStr, OsString};
2use std::io;
3
4use distant_auth::Verifier;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8use crate::common::{Version, WindowsPipeListener};
9use crate::server::{Server, ServerConfig, ServerHandler, WindowsPipeServerRef};
10
11pub struct WindowsPipeServerBuilder<T>(Server<T>);
12
13impl<T> Server<T> {
14 pub fn into_windows_pipe_builder(self) -> WindowsPipeServerBuilder<T> {
16 WindowsPipeServerBuilder(self)
17 }
18}
19
20impl Default for WindowsPipeServerBuilder<()> {
21 fn default() -> Self {
22 Self(Server::new())
23 }
24}
25
26impl<T> WindowsPipeServerBuilder<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) -> WindowsPipeServerBuilder<U> {
32 WindowsPipeServerBuilder(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> WindowsPipeServerBuilder<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<A>(self, addr: A) -> io::Result<WindowsPipeServerRef>
52 where
53 A: AsRef<OsStr> + Send,
54 {
55 let a = addr.as_ref();
56 let listener = WindowsPipeListener::bind(a)?;
57 let addr = listener.addr().to_os_string();
58 let inner = self.0.start(listener)?;
59 Ok(WindowsPipeServerRef { addr, inner })
60 }
61
62 pub async fn start_local<N>(self, name: N) -> io::Result<WindowsPipeServerRef>
64 where
65 Self: Sized,
66 N: AsRef<OsStr> + Send,
67 {
68 let mut addr = OsString::from(r"\\.\pipe\");
69 addr.push(name.as_ref());
70 self.start(addr).await
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use async_trait::async_trait;
77 use distant_auth::DummyAuthHandler;
78 use test_log::test;
79
80 use super::*;
81 use crate::client::Client;
82 use crate::common::Request;
83 use crate::server::RequestCtx;
84
85 pub struct TestServerHandler;
86
87 #[async_trait]
88 impl ServerHandler for TestServerHandler {
89 type Request = String;
90 type Response = String;
91
92 async fn on_request(&self, ctx: RequestCtx<Self::Request, Self::Response>) {
93 ctx.reply.send(ctx.request.payload.to_string()).unwrap();
95 }
96 }
97
98 #[test(tokio::test)]
99 async fn should_invoke_handler_upon_receiving_a_request() {
100 let server = WindowsPipeServerBuilder::default()
101 .handler(TestServerHandler)
102 .verifier(Verifier::none())
103 .start_local(format!("test_pipe_{}", rand::random::<usize>()))
104 .await
105 .expect("Failed to start Windows pipe server");
106
107 let mut client: Client<String, String> = Client::windows_pipe(server.addr())
108 .auth_handler(DummyAuthHandler)
109 .connect()
110 .await
111 .expect("Client failed to connect");
112
113 let response = client
114 .send(Request::new("hello".to_string()))
115 .await
116 .expect("Failed to send message");
117 assert_eq!(response.payload, "hello");
118 }
119}