sheave_core/readers/
handshake.rs

1use std::{
2    future::Future,
3    io::Result as IOResult,
4    pin::Pin,
5    task::{
6        Context as FutureContext,
7        Poll
8    }
9};
10use futures::ready;
11use tokio::io::{
12    AsyncRead,
13    ReadBuf
14};
15use crate::handshake::Handshake;
16
17#[doc(hidden)]
18#[derive(Debug)]
19pub struct HandshakeReader<'a, R: AsyncRead> {
20    reader: Pin<&'a mut R>
21}
22
23#[doc(hidden)]
24impl<R: AsyncRead> Future for HandshakeReader<'_, R> {
25    type Output = IOResult<Handshake>;
26
27    fn poll(mut self: Pin<&mut Self>, cx: &mut FutureContext<'_>) -> Poll<Self::Output> {
28        let mut handshake_bytes: [u8; 1536] = [0; 1536];
29        let mut buf = ReadBuf::new(&mut handshake_bytes);
30        ready!(self.reader.as_mut().poll_read(cx, &mut buf))?;
31        Poll::Ready(Ok(handshake_bytes.into()))
32    }
33}
34
35/// Reads an actual handshake data from streams.
36///
37/// # Examples
38///
39/// ```rust
40/// use std::{
41///     io::Result as IOResult,
42///     pin::pin,
43///     time::Duration,
44/// };
45/// use rand::fill;
46/// use sheave_core::{
47///     handshake::Version,
48///     readers::read_handshake
49/// };
50///
51/// #[tokio::main]
52/// async fn main() -> IOResult<()> {
53///     let mut reader: [u8; 1536] = [0; 1536];
54///     reader[..4].copy_from_slice((Duration::default().as_millis() as u32).to_be_bytes().as_slice());
55///     reader[4..8].copy_from_slice(<[u8; 4]>::from(Version::UNSIGNED).as_slice());
56///     fill(&mut reader[8..]);
57///     let compared = reader;
58///     let handshake = read_handshake(pin!(reader.as_slice())).await?;
59///     assert_eq!(compared.as_slice(), handshake.get_bytes());
60///     Ok(())
61/// }
62/// ```
63pub fn read_handshake<R: AsyncRead>(reader: Pin<&mut R>) -> HandshakeReader<'_, R> {
64    HandshakeReader { reader }
65}
66
67#[cfg(test)]
68mod tests {
69    use std::{
70        pin::pin,
71        time::Duration
72    };
73    use rand::fill;
74    use crate::handshake::Version;
75    use super::*;
76
77    #[tokio::test]
78    async fn read_handshake_bytes() {
79        let mut handshake: [u8; 1536] = [0; 1536];
80        handshake[..4].copy_from_slice((Duration::default().as_millis() as u32).to_be_bytes().as_slice());
81        handshake[4..8].copy_from_slice(<[u8; 4]>::from(Version::UNSIGNED).as_slice());
82        fill(&mut handshake[8..]);
83        let compared = handshake;
84        let result = read_handshake(pin!(handshake.as_slice())).await;
85        assert!(result.is_ok());
86        assert_eq!(compared.as_slice(), result.unwrap().get_bytes())
87    }
88}