use std::sync::Arc;
use futures::lock::Mutex as FutureMutex;
use isahc::AsyncReadResponseExt;
use crate::{
error::Result,
jmap::{connection::JmapConnection, methods::download_request_format, Store},
EnvelopeHash,
};
#[derive(Clone, Debug)]
pub struct JmapOp {
hash: EnvelopeHash,
connection: Arc<FutureMutex<JmapConnection>>,
store: Arc<Store>,
}
impl JmapOp {
pub fn new(
hash: EnvelopeHash,
connection: Arc<FutureMutex<JmapConnection>>,
store: Arc<Store>,
) -> Self {
Self {
hash,
connection,
store,
}
}
pub async fn as_bytes(&self) -> Result<Vec<u8>> {
{
let byte_lck = self.store.byte_cache.lock().await;
if let Some(Some(ret)) = byte_lck.get(&self.hash).map(|c| c.bytes.clone()) {
return Ok(ret.into_bytes());
}
}
let blob_id = self.store.blob_id_store.lock().await[&self.hash].clone();
let mut conn = self.connection.lock().await;
conn.connect().await?;
let (download_url, mail_account_id) = {
let g = self.store.online_status.session_guard().await?;
(g.download_url.clone(), g.mail_account_id())
};
let res_text = conn
.get_async(&download_request_format(
&download_url,
&mail_account_id,
&blob_id,
None,
)?)
.await?
.text()
.await?;
self.store
.byte_cache
.lock()
.await
.entry(self.hash)
.or_default()
.bytes = Some(res_text.clone());
Ok(res_text.into_bytes())
}
}