use alloc::string::String;
use log::trace;
use url::Url;
use crate::{
coroutine::*,
rfc4918::{
DAV, Property, WebdavAuth,
coroutine::WebdavRedirectYield,
follow_redirects::{FollowRedirects, FollowRedirectsError},
parse_multistatus, propfind_body,
request::WebdavRequest,
resolve_href,
},
webdav_try,
};
pub const CURRENT_USER_PRINCIPAL: Property = Property {
ns: DAV,
local: "current-user-principal",
};
#[derive(Debug)]
pub struct CurrentUserPrincipal {
base_url: Url,
state: State,
}
impl CurrentUserPrincipal {
pub fn new(base_url: &Url, auth: &WebdavAuth, user_agent: &str) -> Self {
let request = WebdavRequest::propfind(base_url, auth, user_agent, "")
.depth(0)
.content_type_xml()
.body(propfind_body(&[CURRENT_USER_PRINCIPAL]));
Self {
base_url: base_url.clone(),
state: State::Send(FollowRedirects::new(request)),
}
}
}
impl WebdavCoroutine for CurrentUserPrincipal {
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(CURRENT_USER_PRINCIPAL))
.and_then(|href| resolve_href(&self.base_url, href));
WebdavCoroutineState::Complete(Ok(url))
}
}
}
}
#[derive(Debug)]
enum State {
Send(FollowRedirects),
}