use alloc::string::String;
use log::trace;
use url::Url;
use crate::{
coroutine::*,
rfc4791::calendar::CALENDAR_HOME_SET,
rfc4918::{
WebdavAuth,
coroutine::WebdavRedirectYield,
follow_redirects::{FollowRedirects, FollowRedirectsError},
parse_multistatus, propfind_body,
request::WebdavRequest,
resolve_href,
},
webdav_try,
};
#[derive(Debug)]
pub struct CalendarHomeSet {
base_url: Url,
state: State,
}
impl CalendarHomeSet {
pub fn new(base_url: &Url, auth: &WebdavAuth, user_agent: &str, principal_path: &str) -> Self {
let request = WebdavRequest::propfind(base_url, auth, user_agent, principal_path)
.depth(0)
.content_type_xml()
.body(propfind_body(&[CALENDAR_HOME_SET]));
Self {
base_url: base_url.clone(),
state: State::Send(FollowRedirects::new(request)),
}
}
}
impl WebdavCoroutine for CalendarHomeSet {
type Yield = WebdavRedirectYield;
type Return = Result<Option<Url>, FollowRedirectsError>;
fn resume(&mut self, arg: Option<&[u8]>) -> WebdavCoroutineState<Self::Yield, Self::Return> {
trace!("sending request");
match &mut self.state {
State::Send(send) => {
let ok = webdav_try!(send, arg);
let xml = String::from_utf8_lossy(&ok.body);
let url = parse_multistatus(&xml)
.responses
.iter()
.find_map(|entry| entry.text(CALENDAR_HOME_SET))
.and_then(|href| resolve_href(&self.base_url, href));
WebdavCoroutineState::Complete(Ok(url))
}
}
}
}
#[derive(Debug)]
enum State {
Send(FollowRedirects),
}