io_webdav/rfc4791/item/delete.rs
1//! `delete-item` coroutine: `DELETE` a calendar item by id.
2//!
3//! Supports the optional `If-Match` precondition so callers can gate
4//! the deletion on the last-known ETag (RFC 9110 ยง13.1.1).
5//!
6//! # Example
7//!
8//! ```rust,no_run
9//! use std::{
10//! io::{Read, Write},
11//! net::TcpStream,
12//! };
13//!
14//! use io_webdav::{
15//! coroutine::{WebdavCoroutine, WebdavCoroutineState, WebdavYield},
16//! rfc4791::item::delete::DeleteItem,
17//! rfc4918::WebdavAuth,
18//! };
19//! use url::Url;
20//!
21//! // Ready stream needed (TCP-connected, TLS-negociated)
22//! let mut stream = TcpStream::connect("dav.example.org:443").unwrap();
23//! let mut buf = [0u8; 4096];
24//!
25//! let base_url: Url = "https://dav.example.org/".parse().unwrap();
26//! let auth = WebdavAuth::None;
27//! let mut coroutine = DeleteItem::new(
28//! &base_url,
29//! &auth,
30//! "io-webdav",
31//! "/dav/calendars/personal/",
32//! "event-1",
33//! None,
34//! );
35//! let mut arg = None;
36//!
37//! loop {
38//! match coroutine.resume(arg.take()) {
39//! WebdavCoroutineState::Yielded(WebdavYield::WantsWrite(bytes)) => {
40//! stream.write_all(&bytes).unwrap();
41//! }
42//! WebdavCoroutineState::Yielded(WebdavYield::WantsRead) => {
43//! let n = stream.read(&mut buf).unwrap();
44//! arg = Some(&buf[..n]);
45//! }
46//! WebdavCoroutineState::Complete(Ok(_)) => break,
47//! WebdavCoroutineState::Complete(Err(err)) => panic!("{err}"),
48//! }
49//! }
50//! ```
51
52use alloc::vec::Vec;
53
54use log::trace;
55use url::Url;
56
57use crate::{
58 coroutine::*,
59 rfc4791::item::join_path,
60 rfc4918::{
61 WebdavAuth,
62 delete::Delete,
63 send::{SendError, SendOk},
64 },
65};
66
67/// Coroutine that deletes a calendar item.
68#[derive(Debug)]
69pub struct DeleteItem {
70 state: State,
71}
72
73impl DeleteItem {
74 /// Builds a new `delete-item` coroutine.
75 pub fn new(
76 base_url: &Url,
77 auth: &WebdavAuth,
78 user_agent: &str,
79 calendar_path: &str,
80 item_id: &str,
81 if_match: Option<&str>,
82 ) -> Self {
83 let path = join_path(calendar_path, item_id);
84 Self {
85 state: State::Delete(Delete::new(base_url, auth, user_agent, &path, if_match)),
86 }
87 }
88}
89
90impl WebdavCoroutine for DeleteItem {
91 type Yield = WebdavYield;
92 type Return = Result<SendOk<Vec<u8>>, SendError>;
93
94 fn resume(&mut self, arg: Option<&[u8]>) -> WebdavCoroutineState<Self::Yield, Self::Return> {
95 trace!("sending request");
96 match &mut self.state {
97 State::Delete(delete) => delete.resume(arg),
98 }
99 }
100}
101
102#[derive(Debug)]
103enum State {
104 Delete(Delete),
105}