From a22a2ee35c32b0e2326f3b3399335509082f71f1 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 8 Aug 2021 14:31:18 -0500 Subject: [PATCH] c --- Justfile | 3 +++ imap/bin/greenmail_test.rs | 4 +--- imap/src/client/auth.rs | 2 +- imap/src/client/inner.rs | 10 ++++++++-- imap/src/client/mod.rs | 16 ++++++++++++++++ imap/src/codec.rs | 10 +++++----- imap/src/proto/command.rs | 2 +- imap/src/proto/mod.rs | 2 +- imap/src/proto/response.rs | 9 +++++++++ 9 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Justfile b/Justfile index 5de3e0b..1d5672d 100644 --- a/Justfile +++ b/Justfile @@ -1,2 +1,5 @@ fmt: cargo +nightly fmt --all + +greenmail-test: + cargo run -p imap --bin greenmail-test diff --git a/imap/bin/greenmail_test.rs b/imap/bin/greenmail_test.rs index 97c30fc..7f755fb 100644 --- a/imap/bin/greenmail_test.rs +++ b/imap/bin/greenmail_test.rs @@ -1,4 +1,2 @@ #[tokio::main] -async fn main() { - -} \ No newline at end of file +async fn main() {} diff --git a/imap/src/client/auth.rs b/imap/src/client/auth.rs index 7127603..7999858 100644 --- a/imap/src/client/auth.rs +++ b/imap/src/client/auth.rs @@ -1,7 +1,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; -use crate::proto::command::{Command, CommandLogin}; use crate::client::inner::Inner; +use crate::proto::command::{Command, CommandLogin}; pub trait Client: AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static {} diff --git a/imap/src/client/inner.rs b/imap/src/client/inner.rs index e0fddf9..9477f09 100644 --- a/imap/src/client/inner.rs +++ b/imap/src/client/inner.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use futures::future::FutureExt; +use futures::{future::FutureExt, stream::StreamExt}; use tokio::{ io::{split, AsyncRead, AsyncWrite, ReadHalf, WriteHalf}, sync::oneshot, @@ -71,12 +71,18 @@ where { // set up framed communication let codec = ImapCodec::default(); - let framed = FramedRead::new(stream, codec); + let mut framed = FramedRead::new(stream, codec); let exit = exit.fuse(); pin_mut!(exit); loop { + let next = framed.next().fuse(); + pin_mut!(next); + select! { + msg = next => { + println!("hellosu {:?}", msg); + } _ = exit => break, } } diff --git a/imap/src/client/mod.rs b/imap/src/client/mod.rs index deccb45..712a0dc 100644 --- a/imap/src/client/mod.rs +++ b/imap/src/client/mod.rs @@ -1,3 +1,19 @@ pub mod auth; pub mod inner; pub mod upgrade; + +use anyhow::Result; + +#[derive(Debug, Builder)] +#[builder(build_fn(skip))] +pub struct Config { + // (required for TLS) + hostname: String, + tls: bool, +} + +impl ConfigBuilder { + pub async fn build() -> Result { todo!() } +} + +pub struct Client; diff --git a/imap/src/codec.rs b/imap/src/codec.rs index 388073f..0b4f5f2 100644 --- a/imap/src/codec.rs +++ b/imap/src/codec.rs @@ -1,6 +1,6 @@ use std::io; -use bytes::{BufMut, Bytes, BytesMut}; +use bytes::{Bytes, BytesMut}; use tokio_util::codec::{Decoder, Encoder}; @@ -15,7 +15,7 @@ pub struct ImapCodec { } impl<'a> Decoder for ImapCodec { - type Item = ResponseData; + type Item = OwnedResponse; type Error = io::Error; fn decode(&mut self, buf: &mut BytesMut) -> Result, io::Error> { if self.decode_need_message_bytes > buf.len() { @@ -55,7 +55,7 @@ impl<'a> Decoder for ImapCodec { impl<'a> Encoder<&'a Command<'a>> for ImapCodec { type Error = io::Error; - fn encode(&mut self, msg: &Command, dst: &mut BytesMut) -> Result<(), io::Error> { + fn encode(&mut self, _msg: &Command, _dst: &mut BytesMut) -> Result<(), io::Error> { todo!() // dst.put(&*msg.0); // dst.put_u8(b' '); @@ -66,7 +66,7 @@ impl<'a> Encoder<&'a Command<'a>> for ImapCodec { } #[derive(Debug)] -pub struct ResponseData { +pub struct OwnedResponse { raw: Bytes, // This reference is really scoped to the lifetime of the `raw` // member, but unfortunately Rust does not allow that yet. It @@ -79,7 +79,7 @@ pub struct ResponseData { response: Response<'static>, } -impl ResponseData { +impl OwnedResponse { pub fn request_id(&self) -> Option<&Tag> { match self.response { Response::Done(ResponseDone { ref tag, .. }) => Some(tag), diff --git a/imap/src/proto/command.rs b/imap/src/proto/command.rs index 984b2b5..6d3c253 100644 --- a/imap/src/proto/command.rs +++ b/imap/src/proto/command.rs @@ -40,4 +40,4 @@ pub enum Command<'a> { pub struct CommandLogin<'a> { pub username: &'a str, pub password: &'a str, -} \ No newline at end of file +} diff --git a/imap/src/proto/mod.rs b/imap/src/proto/mod.rs index e70cbce..71054e1 100644 --- a/imap/src/proto/mod.rs +++ b/imap/src/proto/mod.rs @@ -13,4 +13,4 @@ pub mod rfc2234; pub mod rfc3501; #[cfg(feature = "rfc2177-idle")] -pub mod rfc2177; \ No newline at end of file +pub mod rfc2177; diff --git a/imap/src/proto/response.rs b/imap/src/proto/response.rs index 7fb759b..66b9904 100644 --- a/imap/src/proto/response.rs +++ b/imap/src/proto/response.rs @@ -4,6 +4,7 @@ use std::borrow::Cow; pub struct Tag(pub String); #[derive(Debug)] +#[non_exhaustive] pub enum Response<'a> { Done(ResponseDone<'a>), } @@ -16,6 +17,13 @@ pub struct ResponseDone<'a> { pub info: Option>, } +#[derive(Debug)] +pub struct Condition<'a> { + pub status: Status, + pub code: Option>, + pub text: String, +} + #[derive(Debug)] pub enum Status { Ok, @@ -26,6 +34,7 @@ pub enum Status { } #[derive(Debug)] +#[non_exhaustive] pub enum ResponseCode<'a> { Alert, Capabilities(Vec>),