use core::mem;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use log::trace;
use url::Url;
use crate::{
coroutine::*,
rfc4918::{
WebdavAuth,
put::{Put, PutArgs},
read_etag,
send::{SendError, SendOk},
},
rfc6352::card::join_path,
webdav_try,
};
#[derive(Debug)]
pub struct UpdateCard {
uri: String,
state: State,
}
impl UpdateCard {
pub fn new(
base_url: &Url,
auth: &WebdavAuth,
user_agent: &str,
addressbook_path: &str,
uri: &str,
vcard: Vec<u8>,
if_match: Option<&str>,
) -> Self {
let path = join_path(addressbook_path, uri);
let put = Put::new(PutArgs {
base_url,
auth,
user_agent,
path: &path,
content_type: "text/vcard; charset=utf-8",
body: vcard,
if_match,
if_none_match: None,
});
Self {
uri: uri.to_string(),
state: State::Put(put),
}
}
}
impl WebdavCoroutine for UpdateCard {
type Yield = WebdavYield;
type Return = Result<UpdateCardOk, 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 uri = mem::take(&mut self.uri);
WebdavCoroutineState::Complete(Ok(UpdateCardOk { uri, etag }))
}
}
}
}
#[derive(Debug)]
enum State {
Put(Put),
}
#[derive(Clone, Debug)]
pub struct UpdateCardOk {
pub uri: String,
pub etag: Option<String>,
}