forked from KokaKiwi/boitalettres
More flexible responses
This commit is contained in:
parent
fc5f093564
commit
2c43b7686a
4 changed files with 21 additions and 115 deletions
|
@ -1,18 +1,22 @@
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
|
|
||||||
use boitalettres::proto::{Request, Response};
|
use boitalettres::proto::{Request, Response as BalResponse};
|
||||||
use boitalettres::server::accept::addr::{AddrIncoming, AddrStream};
|
use boitalettres::server::accept::addr::{AddrIncoming, AddrStream};
|
||||||
use boitalettres::server::Server;
|
use boitalettres::server::Server;
|
||||||
|
|
||||||
async fn handle_req(req: Request) -> Result<Response> {
|
use imap_codec::types::response::{Response, Data, Status, Capability};
|
||||||
use imap_codec::types::response::{Capability, Data};
|
|
||||||
|
async fn handle_req(req: Request) -> Result<BalResponse> {
|
||||||
|
|
||||||
tracing::debug!("Got request: {:#?}", req);
|
tracing::debug!("Got request: {:#?}", req);
|
||||||
|
|
||||||
let capabilities = vec![Capability::Imap4Rev1, Capability::Idle];
|
let capabilities = vec![Capability::Imap4Rev1, Capability::Idle];
|
||||||
let body = vec![Data::Capability(capabilities)];
|
let res = vec![
|
||||||
|
Response::Data(Data::Capability(capabilities)),
|
||||||
|
Response::Status(Status::ok(Some(req.tag), None, "Done").unwrap()),
|
||||||
|
];
|
||||||
|
|
||||||
Ok(Response::ok("Done")?.with_body(body))
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
105
src/proto/res.rs
105
src/proto/res.rs
|
@ -1,104 +1,3 @@
|
||||||
use imap_codec::types::{
|
use imap_codec::types::response::Response as ImapResponse;
|
||||||
core::{Tag, Text},
|
pub type Response = Vec<ImapResponse>;
|
||||||
response::{Code as ImapCode, Status as ImapStatus},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::body::Body;
|
|
||||||
use crate::errors::{Error, Result};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Response {
|
|
||||||
pub(crate) status: Status,
|
|
||||||
pub(crate) body: Option<Body>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Response {
|
|
||||||
pub fn status(code: StatusCode, msg: &str) -> Result<Response> {
|
|
||||||
Ok(Response {
|
|
||||||
status: Status::new(code, msg)?,
|
|
||||||
body: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ok(msg: &str) -> Result<Response> {
|
|
||||||
Self::status(StatusCode::Ok, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn no(msg: &str) -> Result<Response> {
|
|
||||||
Self::status(StatusCode::No, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bad(msg: &str) -> Result<Response> {
|
|
||||||
Self::status(StatusCode::Bad, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bye(msg: &str) -> Result<Response> {
|
|
||||||
Self::status(StatusCode::Bye, msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Response {
|
|
||||||
pub fn with_extra_code(mut self, extra: ImapCode) -> Self {
|
|
||||||
self.status.extra = Some(extra);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_body(mut self, body: impl Into<Body>) -> Self {
|
|
||||||
self.body = Some(body.into());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Status {
|
|
||||||
pub(crate) code: StatusCode,
|
|
||||||
pub(crate) extra: Option<ImapCode>,
|
|
||||||
pub(crate) text: Text,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum StatusCode {
|
|
||||||
Ok,
|
|
||||||
No,
|
|
||||||
Bad,
|
|
||||||
PreAuth,
|
|
||||||
Bye,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Status {
|
|
||||||
fn new(code: StatusCode, msg: &str) -> Result<Status> {
|
|
||||||
Ok(Status {
|
|
||||||
code,
|
|
||||||
extra: None,
|
|
||||||
text: msg.try_into().map_err(Error::text)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn into_imap(self, tag: Option<Tag>) -> ImapStatus {
|
|
||||||
match self.code {
|
|
||||||
StatusCode::Ok => ImapStatus::Ok {
|
|
||||||
tag,
|
|
||||||
code: self.extra,
|
|
||||||
text: self.text,
|
|
||||||
},
|
|
||||||
StatusCode::No => ImapStatus::No {
|
|
||||||
tag,
|
|
||||||
code: self.extra,
|
|
||||||
text: self.text,
|
|
||||||
},
|
|
||||||
StatusCode::Bad => ImapStatus::Bad {
|
|
||||||
tag,
|
|
||||||
code: self.extra,
|
|
||||||
text: self.text,
|
|
||||||
},
|
|
||||||
StatusCode::PreAuth => ImapStatus::PreAuth {
|
|
||||||
code: self.extra,
|
|
||||||
text: self.text,
|
|
||||||
},
|
|
||||||
StatusCode::Bye => ImapStatus::Bye {
|
|
||||||
code: self.extra,
|
|
||||||
text: self.text,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ use super::pipeline::Connection;
|
||||||
use super::Imap;
|
use super::Imap;
|
||||||
use crate::proto::{Request, Response};
|
use crate::proto::{Request, Response};
|
||||||
|
|
||||||
|
use imap_codec::types::response::{Response as ImapResponse, Status};
|
||||||
|
|
||||||
pub struct Connecting<C, F, S>
|
pub struct Connecting<C, F, S>
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Unpin,
|
C: AsyncRead + AsyncWrite + Unpin,
|
||||||
|
@ -79,8 +81,7 @@ where
|
||||||
{
|
{
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
|
|
||||||
let greeting = Response::ok("Hello").unwrap(); // "Hello" is a valid
|
let greeting = vec![ImapResponse::Status(Status::greeting(None, "Hello").unwrap())]; // "Hello" is a valid greeting
|
||||||
// greeting
|
|
||||||
conn.start_send_unpin((None, greeting)).unwrap();
|
conn.start_send_unpin((None, greeting)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use futures::io::{AsyncRead, AsyncWrite};
|
||||||
use futures::sink::Sink;
|
use futures::sink::Sink;
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
use imap_codec::types::core::Tag;
|
use imap_codec::types::core::Tag;
|
||||||
|
use imap_codec::types::response::Response as ImapResponse;
|
||||||
|
|
||||||
use crate::proto::{Request, Response};
|
use crate::proto::{Request, Response};
|
||||||
|
|
||||||
|
@ -118,12 +119,13 @@ where
|
||||||
let write_buf = &mut self.get_mut().write_buf;
|
let write_buf = &mut self.get_mut().write_buf;
|
||||||
let mut writer = write_buf.writer();
|
let mut writer = write_buf.writer();
|
||||||
|
|
||||||
let body = res.body.into_iter().flat_map(|body| body.into_data());
|
for elem in res {
|
||||||
for data in body {
|
match elem {
|
||||||
data.encode(&mut writer)?;
|
ImapResponse::Status(status) => status.encode(&mut writer)?,
|
||||||
|
ImapResponse::Data(data) => data.encode(&mut writer)?,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status.into_imap(tag).encode(&mut writer)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue