switch to owned responses instead of references
This commit is contained in:
parent
a5dc3eebcb
commit
5db86a9a41
5 changed files with 136 additions and 24 deletions
|
@ -19,12 +19,11 @@ use tokio_rustls::{
|
|||
};
|
||||
|
||||
use crate::command::Command;
|
||||
use crate::types::Response;
|
||||
use crate::response::Response;
|
||||
|
||||
use super::ClientConfig;
|
||||
|
||||
pub type BoxedFunc = Box<dyn Fn()>;
|
||||
pub type ResultMap = Arc<RwLock<HashMap<usize, (Option<String>, Option<Waker>)>>>;
|
||||
pub type ResultMap = Arc<RwLock<HashMap<usize, (Option<Response>, Option<Waker>)>>>;
|
||||
pub type GreetingState = Arc<RwLock<(bool, Option<Waker>)>>;
|
||||
pub const TAG_PREFIX: &str = "panorama";
|
||||
|
||||
|
@ -85,7 +84,7 @@ where
|
|||
}
|
||||
|
||||
/// Sends a command to the server and returns a handle to retrieve the result
|
||||
pub async fn execute(&mut self, cmd: Command) -> Result<String> {
|
||||
pub async fn execute(&mut self, cmd: Command) -> Result<Response> {
|
||||
debug!("executing command {:?}", cmd);
|
||||
let id = self.id;
|
||||
self.id += 1;
|
||||
|
@ -116,13 +115,10 @@ where
|
|||
.execute(cmd)
|
||||
.await
|
||||
.context("error executing CAPABILITY command")?;
|
||||
let (_, resp) = Response::from_bytes(result.as_bytes())
|
||||
.map_err(|err| anyhow!(""))
|
||||
.context("error parsing response from CAPABILITY")?;
|
||||
debug!("cap resp: {:?}", resp);
|
||||
if let Response::Capabilities(caps) = resp {
|
||||
debug!("capabilities: {:?}", caps);
|
||||
}
|
||||
debug!("cap resp: {:?}", result);
|
||||
// if let Response::Capabilities(caps) = resp {
|
||||
// debug!("capabilities: {:?}", caps);
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -217,6 +213,9 @@ where
|
|||
match future::select(fut, fut2).await {
|
||||
Either::Left((_, _)) => {
|
||||
debug!("got a new line");
|
||||
let (_, resp) = crate::parser::parse_response(next_line.as_bytes()).unwrap();
|
||||
let resp = Response::from(resp);
|
||||
debug!("parsed as: {:?}", resp);
|
||||
let next_line = next_line.trim_end_matches('\n').trim_end_matches('\r');
|
||||
|
||||
let mut parts = next_line.split(" ");
|
||||
|
@ -241,7 +240,7 @@ where
|
|||
let mut results = results.write();
|
||||
if let Some((c, w)) = results.get_mut(&id) {
|
||||
// *c = Some(rest.to_string());
|
||||
*c = Some(next_line.to_owned());
|
||||
*c = Some(resp);
|
||||
if let Some(waker) = w.take() {
|
||||
waker.wake();
|
||||
}
|
||||
|
|
|
@ -1,33 +1,141 @@
|
|||
use std::str::FromStr;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use crate::types::{
|
||||
AttributeValue as AttributeValue_, Capability as Capability_, MailboxDatum as MailboxDatum_,
|
||||
RequestId, Response as Response_, ResponseCode as ResponseCode_, State, Status,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Response {
|
||||
Capabilities(Vec<Capability>),
|
||||
Continue {
|
||||
code: Option<ResponseCode>,
|
||||
information: Option<String>,
|
||||
},
|
||||
Done {
|
||||
tag: RequestId,
|
||||
status: Status,
|
||||
code: Option<ResponseCode>,
|
||||
information: Option<String>,
|
||||
},
|
||||
Data {
|
||||
status: Status,
|
||||
code: Option<ResponseCode>,
|
||||
information: Option<String>,
|
||||
},
|
||||
Expunge(u32),
|
||||
Vanished {
|
||||
earlier: bool,
|
||||
uids: Vec<RangeInclusive<u32>>,
|
||||
},
|
||||
Fetch(u32, Vec<AttributeValue>),
|
||||
MailboxData(MailboxDatum),
|
||||
}
|
||||
|
||||
impl FromStr for Response {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
todo!()
|
||||
impl<'a> From<Response_<'a>> for Response {
|
||||
fn from(b: Response_) -> Self {
|
||||
use Response_::*;
|
||||
match b {
|
||||
Capabilities(caps) => {
|
||||
Response::Capabilities(caps.into_iter().map(Capability::from).collect())
|
||||
}
|
||||
Continue { code, information } => Response::Continue {
|
||||
code: code.map(ResponseCode::from),
|
||||
information: information.map(str::to_owned),
|
||||
},
|
||||
Done {
|
||||
tag,
|
||||
status,
|
||||
code,
|
||||
information,
|
||||
} => Response::Done {
|
||||
tag,
|
||||
status,
|
||||
code: code.map(ResponseCode::from),
|
||||
information: information.map(str::to_owned),
|
||||
},
|
||||
Data {
|
||||
status,
|
||||
code,
|
||||
information,
|
||||
} => Response::Data {
|
||||
status,
|
||||
code: code.map(ResponseCode::from),
|
||||
information: information.map(str::to_owned),
|
||||
},
|
||||
Expunge(n) => Response::Expunge(n),
|
||||
Vanished {earlier, uids} => Response::Vanished{earlier, uids},
|
||||
_ => todo!("nyi: {:?}", b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Capability {
|
||||
Imap4rev1,
|
||||
Auth(String),
|
||||
Atom(String),
|
||||
}
|
||||
|
||||
pub struct RequestId(pub String);
|
||||
|
||||
pub enum Status {
|
||||
Ok,
|
||||
No,
|
||||
impl<'a> From<Capability_<'a>> for Capability {
|
||||
fn from(b: Capability_) -> Self {
|
||||
use Capability_::*;
|
||||
match b {
|
||||
Imap4rev1 => Capability::Imap4rev1,
|
||||
Auth(s) => Capability::Auth(s.to_owned()),
|
||||
Atom(s) => Capability::Atom(s.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ResponseCode {}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ResponseCode {
|
||||
Alert,
|
||||
BadCharset(Option<Vec<String>>),
|
||||
Capabilities(Vec<Capability>),
|
||||
HighestModSeq(u64), // RFC 4551, section 3.1.1
|
||||
Parse,
|
||||
PermanentFlags(Vec<String>),
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
TryCreate,
|
||||
UidNext(u32),
|
||||
UidValidity(u32),
|
||||
Unseen(u32),
|
||||
AppendUid(u32, Vec<UidSetMember>),
|
||||
CopyUid(u32, Vec<UidSetMember>, Vec<UidSetMember>),
|
||||
UidNotSticky,
|
||||
}
|
||||
|
||||
impl<'a> From<ResponseCode_<'a>> for ResponseCode {
|
||||
fn from(b: ResponseCode_) -> Self {
|
||||
use ResponseCode_::*;
|
||||
match b {
|
||||
Alert => ResponseCode::Alert,
|
||||
BadCharset(s) => {
|
||||
ResponseCode::BadCharset(s.map(|v| v.into_iter().map(str::to_owned).collect()))
|
||||
}
|
||||
Capabilities(v) => {
|
||||
ResponseCode::Capabilities(v.into_iter().map(Capability::from).collect())
|
||||
}
|
||||
HighestModSeq(n) => ResponseCode::HighestModSeq(n),
|
||||
Parse => ResponseCode::Parse,
|
||||
_ => todo!("nyi: {:?}", b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UidSetMember {
|
||||
UidRange(RangeInclusive<u32>),
|
||||
Uid(u32),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum AttributeValue {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum MailboxDatum {
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl<'a> Response<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Status {
|
||||
Ok,
|
||||
No,
|
||||
|
|
|
@ -89,5 +89,10 @@ async fn imap_main(acct: MailAccountConfig) -> Result<()> {
|
|||
|
||||
// debug!("sending CAPABILITY");
|
||||
// let result = unauth.capabilities().await?;
|
||||
|
||||
loop {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
||||
debug!("heartbeat");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue