rcon/
rt_async_std.rs

1use async_std::io::{Read, Write};
2use async_std::net::{TcpStream, ToSocketAddrs};
3use async_std::task::ready;
4use std::io::{self, IoSlice};
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use tokio::io::{AsyncRead as TokioRead, AsyncWrite as TokioWrite, ReadBuf};
8
9use crate::{Builder, Connection, Result};
10
11impl Connection<AsyncStdStream> {
12    /// Connect to an rcon server using the [async-std](async_std) runtime.
13    ///
14    /// By default this enables Minecraft quirks.
15    /// If you need to customize this behaviour, use a [`Builder`].
16    #[cfg_attr(doc_cfg, doc(cfg(feature = "rt-async-std")))]
17    pub async fn connect<A: ToSocketAddrs>(address: A, password: &str) -> Result<Self> {
18        Self::builder()
19            .enable_minecraft_quirks(true)
20            .connect(address, password)
21            .await
22    }
23}
24
25impl Builder<AsyncStdStream> {
26    /// Connect to an rcon server using the [async-std](async_std) runtime.
27    #[cfg_attr(doc_cfg, doc(cfg(feature = "rt-async-std")))]
28    #[cfg_attr(not(feature = "tokio"), allow(unused_mut))]
29    pub async fn connect<A: ToSocketAddrs>(
30        mut self,
31        address: A,
32        password: &str,
33    ) -> Result<Connection<AsyncStdStream>> {
34        // If the `rt-tokio` feature flag is also enabled the sleep_fn will use it by default, so
35        // we have to change it to use async-std instead.
36        #[cfg(feature = "rt-tokio")]
37        if let crate::SleepFn::Tokio = self.sleep_fn {
38            self.sleep_fn = crate::SleepFn::AsyncStd;
39        }
40        self.handshake(AsyncStdStream(TcpStream::connect(address).await?), password)
41            .await
42    }
43}
44
45/// The inner transport of an [async-std](async_std) rcon connection.
46///
47/// This is a simple wrapper around a [`TcpStream`] that implements Tokio's I/O traits so it can be
48/// used inside [`Connection`].
49#[derive(Debug)]
50#[cfg_attr(doc_cfg, doc(cfg(feature = "rt-async-std")))]
51pub struct AsyncStdStream(pub TcpStream);
52
53impl TokioRead for AsyncStdStream {
54    fn poll_read(
55        mut self: Pin<&mut Self>,
56        cx: &mut Context<'_>,
57        buf: &mut ReadBuf<'_>,
58    ) -> Poll<io::Result<()>> {
59        let bytes = ready!(Pin::new(&mut self.0).poll_read(cx, buf.initialize_unfilled()))?;
60        buf.advance(bytes);
61        Poll::Ready(Ok(()))
62    }
63}
64
65impl TokioWrite for AsyncStdStream {
66    fn poll_write(
67        mut self: Pin<&mut Self>,
68        cx: &mut Context<'_>,
69        buf: &[u8],
70    ) -> Poll<io::Result<usize>> {
71        Pin::new(&mut self.0).poll_write(cx, buf)
72    }
73    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
74        Pin::new(&mut self.0).poll_flush(cx)
75    }
76    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
77        Pin::new(&mut self.0).poll_close(cx)
78    }
79    fn poll_write_vectored(
80        mut self: Pin<&mut Self>,
81        cx: &mut Context<'_>,
82        bufs: &[IoSlice<'_>],
83    ) -> Poll<io::Result<usize>> {
84        Pin::new(&mut self.0).poll_write_vectored(cx, bufs)
85    }
86}