Skip to content

Commit e6961b5

Browse files
committed
Simplify ImapTransport abstraction
1 parent d500134 commit e6961b5

File tree

4 files changed

+34
-59
lines changed

4 files changed

+34
-59
lines changed

tokio-imap/examples/basic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use tokio_imap::client::builder::{
1010
};
1111
use tokio_imap::proto::ResponseData;
1212
use tokio_imap::types::{Attribute, AttributeValue, Response};
13-
use tokio_imap::{ImapClient, TlsClient};
13+
use tokio_imap::TlsClient;
1414

1515
fn main() {
1616
let mut args = std::env::args();

tokio-imap/src/client/mod.rs

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use native_tls::TlsConnector;
88
use std::io;
99
use std::net::ToSocketAddrs;
1010

11+
use tokio::io::{AsyncRead, AsyncWrite};
1112
use tokio::net::tcp::{ConnectFuture, TcpStream};
1213
use tokio_codec::Decoder;
13-
use tokio_tls::{self, Connect};
14+
use tokio_tls::{self, Connect, TlsStream};
1415

15-
use crate::proto::{ImapCodec, ImapTls, ImapTransport, ResponseData};
16+
use crate::proto::{ImapCodec, ImapTransport, ResponseData};
1617
use imap_proto::builders::command::Command;
1718
use imap_proto::{Request, RequestId, State};
1819

@@ -23,28 +24,29 @@ pub mod builder {
2324
};
2425
}
2526

26-
pub trait ImapClient {
27-
type Transport: ImapTransport;
28-
fn into_parts(self) -> (Self::Transport, ClientState);
29-
fn rebuild(transport: Self::Transport, state: ClientState) -> Self;
27+
pub type TlsClient = Client<TlsStream<TcpStream>>;
3028

31-
fn call(self, cmd: Command) -> ResponseStream<Self>
32-
where
33-
Self: ImapClient + Sized,
34-
{
35-
let (transport, mut state) = self.into_parts();
29+
pub struct Client<T> {
30+
transport: ImapTransport<T>,
31+
state: ClientState,
32+
}
33+
34+
impl<T> Client<T>
35+
where
36+
T: AsyncRead + AsyncWrite,
37+
{
38+
pub fn call(self, cmd: Command) -> ResponseStream<T> {
39+
let Client {
40+
transport,
41+
mut state,
42+
} = self;
3643
let request_id = state.request_ids.next().unwrap(); // safe: never returns Err
3744
let (cmd_bytes, next_state) = cmd.into_parts();
3845
let future = transport.send(Request(request_id.clone(), cmd_bytes));
3946
ResponseStream::new(future, state, request_id, next_state)
4047
}
4148
}
4249

43-
pub struct TlsClient {
44-
transport: ImapTls,
45-
state: ClientState,
46-
}
47-
4850
impl TlsClient {
4951
pub fn connect(server: &str) -> io::Result<ImapConnectFuture> {
5052
let addr = (server, 993).to_socket_addrs()?.next().ok_or_else(|| {
@@ -60,37 +62,24 @@ impl TlsClient {
6062
}
6163
}
6264

63-
impl ImapClient for TlsClient {
64-
type Transport = ImapTls;
65-
66-
fn into_parts(self) -> (ImapTls, ClientState) {
67-
let Self { transport, state } = self;
68-
(transport, state)
69-
}
70-
71-
fn rebuild(transport: ImapTls, state: ClientState) -> TlsClient {
72-
TlsClient { transport, state }
73-
}
74-
}
75-
76-
pub struct ResponseStream<E>
65+
pub struct ResponseStream<T>
7766
where
78-
E: ImapClient,
67+
T: AsyncRead + AsyncWrite,
7968
{
80-
future: Option<Send<E::Transport>>,
81-
transport: Option<E::Transport>,
69+
future: Option<Send<ImapTransport<T>>>,
70+
transport: Option<ImapTransport<T>>,
8271
state: Option<ClientState>,
8372
request_id: RequestId,
8473
next_state: Option<State>,
8574
done: bool,
8675
}
8776

88-
impl<E> ResponseStream<E>
77+
impl<T> ResponseStream<T>
8978
where
90-
E: ImapClient,
79+
T: AsyncRead + AsyncWrite,
9180
{
9281
pub fn new(
93-
future: Send<E::Transport>,
82+
future: Send<ImapTransport<T>>,
9483
state: ClientState,
9584
request_id: RequestId,
9685
next_state: Option<State>,
@@ -106,12 +95,12 @@ where
10695
}
10796
}
10897

109-
impl<E> StateStream for ResponseStream<E>
98+
impl<T> StateStream for ResponseStream<T>
11099
where
111-
E: ImapClient,
100+
T: AsyncRead + AsyncWrite,
112101
{
113102
type Item = ResponseData;
114-
type State = E;
103+
type State = Client<T>;
115104
type Error = io::Error;
116105
fn poll(&mut self) -> Poll<StreamEvent<Self::Item, Self::State>, Self::Error> {
117106
if let Some(mut future) = self.future.take() {
@@ -137,9 +126,7 @@ where
137126
if let Some(next_state) = self.next_state.take() {
138127
state.state = next_state;
139128
}
140-
return Ok(Async::Ready(StreamEvent::Done(E::rebuild(
141-
transport, state,
142-
))));
129+
return Ok(Async::Ready(StreamEvent::Done(Client { transport, state })));
143130
}
144131
match transport.poll() {
145132
Ok(Async::Ready(Some(rsp))) => {
@@ -165,7 +152,7 @@ pub enum ImapConnectFuture {
165152
#[doc(hidden)]
166153
TlsHandshake(Connect<TcpStream>),
167154
#[doc(hidden)]
168-
ServerGreeting(Option<ImapTls>),
155+
ServerGreeting(Option<ImapTransport<TlsStream<TcpStream>>>),
169156
}
170157

171158
impl Future for ImapConnectFuture {

tokio-imap/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ extern crate futures;
44
pub mod client;
55
pub mod proto;
66

7-
pub use crate::client::{ImapClient, TlsClient};
7+
pub use crate::client::{Client, TlsClient};
88

99
pub mod types {
1010
pub use imap_proto::types::*;

tokio-imap/src/proto.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use bytes::{BufMut, Bytes, BytesMut};
22

3-
use futures;
4-
53
use nom::{self, Needed};
64

75
use imap_proto;
@@ -10,9 +8,7 @@ use imap_proto::types::{Request, RequestId, Response};
108
use std::io;
119
use std::mem;
1210

13-
use tokio::net::TcpStream;
14-
use tokio_codec::{Decoder, Encoder, Framed};
15-
use tokio_tls::TlsStream;
11+
use tokio::codec::{Decoder, Encoder, Framed};
1612

1713
pub struct ImapCodec {
1814
decode_need_message_bytes: usize,
@@ -101,12 +97,4 @@ impl ResponseData {
10197
}
10298
}
10399

104-
pub type ImapTls = Framed<TlsStream<TcpStream>, ImapCodec>;
105-
106-
impl ImapTransport for ImapTls {}
107-
108-
pub trait ImapTransport:
109-
futures::Stream<Item = ResponseData, Error = io::Error>
110-
+ futures::Sink<SinkItem = Request, SinkError = io::Error>
111-
{
112-
}
100+
pub type ImapTransport<T> = Framed<T, ImapCodec>;

0 commit comments

Comments
 (0)