use core::mem;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use log::trace;
use url::Url;
use crate::{
coroutine::*,
rfc4791::item::join_path,
rfc4918::{
WebdavAuth,
put::{Put, PutArgs},
read_etag,
send::{SendError, SendOk},
},
webdav_try,
};
#[derive(Debug)]
pub struct UpdateItem {
id: String,
state: State,
}
impl UpdateItem {
pub fn new(
base_url: &Url,
auth: &WebdavAuth,
user_agent: &str,
calendar_path: &str,
id: &str,
ical: Vec<u8>,
if_match: Option<&str>,
) -> Self {
let path = join_path(calendar_path, id);
let put = Put::new(PutArgs {
base_url,
auth,
user_agent,
path: &path,
content_type: "text/calendar; charset=utf-8",
body: ical,
if_match,
if_none_match: None,
});
Self {
id: id.to_string(),
state: State::Put(put),
}
}
}
impl WebdavCoroutine for UpdateItem {
type Yield = WebdavYield;
type Return = Result<UpdateItemOk, SendError>;
fn resume(&mut self, arg: Option<&[u8]>) -> WebdavCoroutineState<Self::Yield, Self::Return> {
trace!("sending request");
match &mut self.state {
State::Put(put) => {
let SendOk { response, .. } = webdav_try!(put, arg);
let etag = read_etag(&response);
let id = mem::take(&mut self.id);
WebdavCoroutineState::Complete(Ok(UpdateItemOk { id, etag }))
}
}
}
}
#[derive(Debug)]
enum State {
Put(Put),
}
#[derive(Clone, Debug)]
pub struct UpdateItemOk {
pub id: String,
pub etag: Option<String>,
}