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 CreateItem {
id: String,
state: State,
}
impl CreateItem {
pub fn new(
base_url: &Url,
auth: &WebdavAuth,
user_agent: &str,
calendar_path: &str,
id: &str,
ical: Vec<u8>,
) -> 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: None,
if_none_match: Some("*"),
});
Self {
id: id.to_string(),
state: State::Put(put),
}
}
}
impl WebdavCoroutine for CreateItem {
type Yield = WebdavYield;
type Return = Result<CreateItemOk, 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(CreateItemOk { id, etag }))
}
}
}
}
#[derive(Debug)]
enum State {
Put(Put),
}
#[derive(Clone, Debug)]
pub struct CreateItemOk {
pub id: String,
pub etag: Option<String>,
}