boitalettres/src/proto/res.rs

105 lines
2.4 KiB
Rust

use imap_codec::types::{
core::{Tag, Text},
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,
},
}
}
}