1use std::io;
2
3#[cfg(windows)]
4async fn windows_main() -> io::Result<()> {
5 use tokio::io::AsyncWriteExt;
6 use tokio::io::{AsyncBufReadExt, BufReader};
7 use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
8
9 const PIPE_NAME: &str = r"\\.\pipe\named-pipe-single-client";
10
11 let server = ServerOptions::new().create(PIPE_NAME)?;
12
13 let server = tokio::spawn(async move {
14 // Note: we wait for a client to connect.
15 server.connect().await?;
16
17 let mut server = BufReader::new(server);
18
19 let mut buf = String::new();
20 server.read_line(&mut buf).await?;
21 server.write_all(b"pong\n").await?;
22 Ok::<_, io::Error>(buf)
23 });
24
25 let client = tokio::spawn(async move {
26 // There's no need to use a connect loop here, since we know that the
27 // server is already up - `open` was called before spawning any of the
28 // tasks.
29 let client = ClientOptions::new().open(PIPE_NAME)?;
30
31 let mut client = BufReader::new(client);
32
33 let mut buf = String::new();
34 client.write_all(b"ping\n").await?;
35 client.read_line(&mut buf).await?;
36 Ok::<_, io::Error>(buf)
37 });
38
39 let (server, client) = tokio::try_join!(server, client)?;
40
41 assert_eq!(server?, "ping\n");
42 assert_eq!(client?, "pong\n");
43
44 Ok(())
45}
46
47#[tokio::main]
48async fn main() -> io::Result<()> {
49 #[cfg(windows)]
50 {
51 windows_main().await?;
52 }
53
54 #[cfg(not(windows))]
55 {
56 println!("Named pipes are only supported on Windows!");
57 }
58
59 Ok(())
60}
61