use crate::Client;
use crate::error::Error;
use crate::mailbox::Mailbox;
use bytes::Bytes;
use futures::Stream;
use jiff::Timestamp;
use serde::Deserialize;
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct MessagePreviewData {
#[serde(rename = "_id")]
id: String,
#[serde(with = "jiff::fmt::serde::timestamp::second::required")]
received_at: Timestamp,
from: String,
subject: String,
body_preview: String,
attachments_count: u32,
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct MessageData {
#[serde(flatten)]
preview: MessagePreviewData,
user_id: String,
mailbox: String,
body_html: String,
attachments: Vec<AttachmentMetadata>,
created_at: Timestamp,
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
pub struct AttachmentMetadata {
#[serde(rename = "_id")]
id: u32,
filename: String,
size: u64,
#[serde(rename = "mimetype")]
mime_type: String,
cid: String,
}
impl AttachmentMetadata {
pub fn id(&self) -> u32 {
self.id
}
pub fn filename(&self) -> &str {
&self.filename
}
pub fn size(&self) -> u64 {
self.size
}
pub fn mime_type(&self) -> &str {
&self.mime_type
}
pub fn cid(&self) -> &str {
&self.cid
}
}
pub struct MessagePreview<'a> {
client: &'a Client,
mailbox: &'a Mailbox<'a>,
data: MessagePreviewData,
}
impl<'a> MessagePreview<'a> {
pub(crate) fn new(
client: &'a Client,
mailbox: &'a Mailbox<'a>,
data: MessagePreviewData,
) -> Self {
Self {
client,
mailbox,
data,
}
}
pub fn id(&self) -> &str {
&self.data.id
}
pub fn received_at(&self) -> Timestamp {
self.data.received_at
}
pub fn from(&self) -> &str {
&self.data.from
}
pub fn subject(&self) -> &str {
&self.data.subject
}
pub fn body_preview(&self) -> &str {
&self.data.body_preview
}
pub fn attachments_count(&self) -> u32 {
self.data.attachments_count
}
pub async fn to_message(self) -> Result<Message<'a>, Error> {
let data = self
.client
.get_message(self.mailbox.token(), &self.data.id)
.await?;
Ok(Message::new(self.client, self.mailbox, data))
}
}
pub struct Message<'a> {
client: &'a Client,
mailbox: &'a Mailbox<'a>,
data: MessageData,
}
impl<'a> Message<'a> {
fn new(client: &'a Client, mailbox: &'a Mailbox<'a>, data: MessageData) -> Self {
Self {
client,
mailbox,
data,
}
}
pub fn id(&self) -> &str {
&self.data.preview.id
}
pub fn received_at(&self) -> Timestamp {
self.data.preview.received_at
}
pub fn from(&self) -> &str {
&self.data.preview.from
}
pub fn subject(&self) -> &str {
&self.data.preview.subject
}
pub fn body_preview(&self) -> &str {
&self.data.preview.body_preview
}
pub fn attachments_count(&self) -> u32 {
self.data.preview.attachments_count
}
pub fn body_html(&self) -> &str {
&self.data.body_html
}
pub fn attachments(&self) -> &[AttachmentMetadata] {
&self.data.attachments
}
pub fn created_at(&self) -> Timestamp {
self.data.created_at
}
pub async fn get_attachment(
&self,
id: u32,
) -> Result<impl Stream<Item = Result<Bytes, Error>>, Error> {
self.client
.get_attachment(self.mailbox.token(), &self.data.preview.id, id)
.await
}
}