c
This commit is contained in:
parent
c1e770e050
commit
a22a2ee35c
9 changed files with 45 additions and 13 deletions
3
Justfile
3
Justfile
|
@ -1,2 +1,5 @@
|
||||||
fmt:
|
fmt:
|
||||||
cargo +nightly fmt --all
|
cargo +nightly fmt --all
|
||||||
|
|
||||||
|
greenmail-test:
|
||||||
|
cargo run -p imap --bin greenmail-test
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use tokio::io::{AsyncRead, AsyncWrite};
|
use tokio::io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
use crate::proto::command::{Command, CommandLogin};
|
|
||||||
use crate::client::inner::Inner;
|
use crate::client::inner::Inner;
|
||||||
|
use crate::proto::command::{Command, CommandLogin};
|
||||||
|
|
||||||
pub trait Client: AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static {}
|
pub trait Client: AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static {}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use futures::future::FutureExt;
|
use futures::{future::FutureExt, stream::StreamExt};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{split, AsyncRead, AsyncWrite, ReadHalf, WriteHalf},
|
io::{split, AsyncRead, AsyncWrite, ReadHalf, WriteHalf},
|
||||||
sync::oneshot,
|
sync::oneshot,
|
||||||
|
@ -71,12 +71,18 @@ where
|
||||||
{
|
{
|
||||||
// set up framed communication
|
// set up framed communication
|
||||||
let codec = ImapCodec::default();
|
let codec = ImapCodec::default();
|
||||||
let framed = FramedRead::new(stream, codec);
|
let mut framed = FramedRead::new(stream, codec);
|
||||||
|
|
||||||
let exit = exit.fuse();
|
let exit = exit.fuse();
|
||||||
pin_mut!(exit);
|
pin_mut!(exit);
|
||||||
loop {
|
loop {
|
||||||
|
let next = framed.next().fuse();
|
||||||
|
pin_mut!(next);
|
||||||
|
|
||||||
select! {
|
select! {
|
||||||
|
msg = next => {
|
||||||
|
println!("hellosu {:?}", msg);
|
||||||
|
}
|
||||||
_ = exit => break,
|
_ = exit => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod inner;
|
pub mod inner;
|
||||||
pub mod upgrade;
|
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<Client> { todo!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
|
||||||
use tokio_util::codec::{Decoder, Encoder};
|
use tokio_util::codec::{Decoder, Encoder};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub struct ImapCodec {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Decoder for ImapCodec {
|
impl<'a> Decoder for ImapCodec {
|
||||||
type Item = ResponseData;
|
type Item = OwnedResponse;
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
|
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
|
||||||
if self.decode_need_message_bytes > buf.len() {
|
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 {
|
impl<'a> Encoder<&'a Command<'a>> for ImapCodec {
|
||||||
type Error = io::Error;
|
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!()
|
todo!()
|
||||||
// dst.put(&*msg.0);
|
// dst.put(&*msg.0);
|
||||||
// dst.put_u8(b' ');
|
// dst.put_u8(b' ');
|
||||||
|
@ -66,7 +66,7 @@ impl<'a> Encoder<&'a Command<'a>> for ImapCodec {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ResponseData {
|
pub struct OwnedResponse {
|
||||||
raw: Bytes,
|
raw: Bytes,
|
||||||
// This reference is really scoped to the lifetime of the `raw`
|
// This reference is really scoped to the lifetime of the `raw`
|
||||||
// member, but unfortunately Rust does not allow that yet. It
|
// member, but unfortunately Rust does not allow that yet. It
|
||||||
|
@ -79,7 +79,7 @@ pub struct ResponseData {
|
||||||
response: Response<'static>,
|
response: Response<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseData {
|
impl OwnedResponse {
|
||||||
pub fn request_id(&self) -> Option<&Tag> {
|
pub fn request_id(&self) -> Option<&Tag> {
|
||||||
match self.response {
|
match self.response {
|
||||||
Response::Done(ResponseDone { ref tag, .. }) => Some(tag),
|
Response::Done(ResponseDone { ref tag, .. }) => Some(tag),
|
||||||
|
|
|
@ -40,4 +40,4 @@ pub enum Command<'a> {
|
||||||
pub struct CommandLogin<'a> {
|
pub struct CommandLogin<'a> {
|
||||||
pub username: &'a str,
|
pub username: &'a str,
|
||||||
pub password: &'a str,
|
pub password: &'a str,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,4 @@ pub mod rfc2234;
|
||||||
pub mod rfc3501;
|
pub mod rfc3501;
|
||||||
|
|
||||||
#[cfg(feature = "rfc2177-idle")]
|
#[cfg(feature = "rfc2177-idle")]
|
||||||
pub mod rfc2177;
|
pub mod rfc2177;
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::borrow::Cow;
|
||||||
pub struct Tag(pub String);
|
pub struct Tag(pub String);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum Response<'a> {
|
pub enum Response<'a> {
|
||||||
Done(ResponseDone<'a>),
|
Done(ResponseDone<'a>),
|
||||||
}
|
}
|
||||||
|
@ -16,6 +17,13 @@ pub struct ResponseDone<'a> {
|
||||||
pub info: Option<Cow<'a, str>>,
|
pub info: Option<Cow<'a, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Condition<'a> {
|
||||||
|
pub status: Status,
|
||||||
|
pub code: Option<ResponseCode<'a>>,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Status {
|
pub enum Status {
|
||||||
Ok,
|
Ok,
|
||||||
|
@ -26,6 +34,7 @@ pub enum Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum ResponseCode<'a> {
|
pub enum ResponseCode<'a> {
|
||||||
Alert,
|
Alert,
|
||||||
Capabilities(Vec<Capability<'a>>),
|
Capabilities(Vec<Capability<'a>>),
|
||||||
|
|
Loading…
Reference in a new issue