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::command::Command;
|
||||||
use crate::types::Response;
|
use crate::response::Response;
|
||||||
|
|
||||||
use super::ClientConfig;
|
use super::ClientConfig;
|
||||||
|
|
||||||
pub type BoxedFunc = Box<dyn Fn()>;
|
pub type ResultMap = Arc<RwLock<HashMap<usize, (Option<Response>, Option<Waker>)>>>;
|
||||||
pub type ResultMap = Arc<RwLock<HashMap<usize, (Option<String>, Option<Waker>)>>>;
|
|
||||||
pub type GreetingState = Arc<RwLock<(bool, Option<Waker>)>>;
|
pub type GreetingState = Arc<RwLock<(bool, Option<Waker>)>>;
|
||||||
pub const TAG_PREFIX: &str = "panorama";
|
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
|
/// 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);
|
debug!("executing command {:?}", cmd);
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
self.id += 1;
|
self.id += 1;
|
||||||
|
@ -116,13 +115,10 @@ where
|
||||||
.execute(cmd)
|
.execute(cmd)
|
||||||
.await
|
.await
|
||||||
.context("error executing CAPABILITY command")?;
|
.context("error executing CAPABILITY command")?;
|
||||||
let (_, resp) = Response::from_bytes(result.as_bytes())
|
debug!("cap resp: {:?}", result);
|
||||||
.map_err(|err| anyhow!(""))
|
// if let Response::Capabilities(caps) = resp {
|
||||||
.context("error parsing response from CAPABILITY")?;
|
// debug!("capabilities: {:?}", caps);
|
||||||
debug!("cap resp: {:?}", resp);
|
// }
|
||||||
if let Response::Capabilities(caps) = resp {
|
|
||||||
debug!("capabilities: {:?}", caps);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +213,9 @@ where
|
||||||
match future::select(fut, fut2).await {
|
match future::select(fut, fut2).await {
|
||||||
Either::Left((_, _)) => {
|
Either::Left((_, _)) => {
|
||||||
debug!("got a new line");
|
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 next_line = next_line.trim_end_matches('\n').trim_end_matches('\r');
|
||||||
|
|
||||||
let mut parts = next_line.split(" ");
|
let mut parts = next_line.split(" ");
|
||||||
|
@ -241,7 +240,7 @@ where
|
||||||
let mut results = results.write();
|
let mut results = results.write();
|
||||||
if let Some((c, w)) = results.get_mut(&id) {
|
if let Some((c, w)) = results.get_mut(&id) {
|
||||||
// *c = Some(rest.to_string());
|
// *c = Some(rest.to_string());
|
||||||
*c = Some(next_line.to_owned());
|
*c = Some(resp);
|
||||||
if let Some(waker) = w.take() {
|
if let Some(waker) = w.take() {
|
||||||
waker.wake();
|
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 {
|
pub enum Response {
|
||||||
Capabilities(Vec<Capability>),
|
Capabilities(Vec<Capability>),
|
||||||
|
Continue {
|
||||||
|
code: Option<ResponseCode>,
|
||||||
|
information: Option<String>,
|
||||||
|
},
|
||||||
Done {
|
Done {
|
||||||
tag: RequestId,
|
tag: RequestId,
|
||||||
status: Status,
|
status: Status,
|
||||||
code: Option<ResponseCode>,
|
code: Option<ResponseCode>,
|
||||||
information: Option<String>,
|
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 {
|
impl<'a> From<Response_<'a>> for Response {
|
||||||
type Err = anyhow::Error;
|
fn from(b: Response_) -> Self {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
use Response_::*;
|
||||||
todo!()
|
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 {
|
pub enum Capability {
|
||||||
Imap4rev1,
|
Imap4rev1,
|
||||||
Auth(String),
|
Auth(String),
|
||||||
Atom(String),
|
Atom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RequestId(pub String);
|
impl<'a> From<Capability_<'a>> for Capability {
|
||||||
|
fn from(b: Capability_) -> Self {
|
||||||
pub enum Status {
|
use Capability_::*;
|
||||||
Ok,
|
match b {
|
||||||
No,
|
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 {
|
pub enum Status {
|
||||||
Ok,
|
Ok,
|
||||||
No,
|
No,
|
||||||
|
|
|
@ -89,5 +89,10 @@ async fn imap_main(acct: MailAccountConfig) -> Result<()> {
|
||||||
|
|
||||||
// debug!("sending CAPABILITY");
|
// debug!("sending CAPABILITY");
|
||||||
// let result = unauth.capabilities().await?;
|
// let result = unauth.capabilities().await?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
||||||
|
debug!("heartbeat");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue