rip_starttls/imap/
async_std.rs

1//! # Async-std
2//!
3//! This module contains the async I/O connector based on
4//! [`async_std`] for [`RipStarttls`](super::RipStarttls).
5
6use std::io::Result;
7
8use async_std::{
9    io::{BufReadExt, BufReader, WriteExt},
10    net::TcpStream,
11};
12
13use super::{Event, State};
14
15#[derive(Clone, Debug, Default, Eq, PartialEq)]
16pub struct RipStarttls {
17    state: super::RipStarttls,
18}
19
20impl RipStarttls {
21    pub fn new(handshake_discarded: bool) -> Self {
22        let state = super::RipStarttls::new(handshake_discarded);
23        Self { state }
24    }
25
26    pub async fn do_starttls_prefix(mut self, mut stream: TcpStream) -> Result<TcpStream> {
27        let mut event = None;
28
29        while let Some(output) = self.state.resume(event.take()) {
30            match output {
31                State::DiscardHandshake => {
32                    let mut line = String::new();
33                    let mut reader = BufReader::new(stream);
34                    reader.read_line(&mut line).await?;
35                    event = Some(Event::HandshakeDiscarded(line));
36                    stream = reader.into_inner();
37                }
38                State::WriteStarttlsCommand => {
39                    let cmd = super::RipStarttls::COMMAND;
40                    let count = stream.write(cmd.as_bytes()).await?;
41                    event = Some(Event::StarttlsCommandWrote(count));
42                }
43                State::DiscardResponse => {
44                    let mut line = String::new();
45                    let mut reader = BufReader::new(stream);
46                    reader.read_line(&mut line).await?;
47                    event = Some(Event::ResponseDiscarded(line));
48                    stream = reader.into_inner();
49                }
50            }
51        }
52
53        Ok(stream)
54    }
55}