Skip to main content

io_webdav/rfc6352/card/
delete.rs

1//! `delete-card` coroutine: `DELETE` a card by its resource name.
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//!     rfc4918::WebdavAuth,
17//!     rfc6352::card::delete::DeleteCard,
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 = DeleteCard::new(
28//!     &base_url,
29//!     &auth,
30//!     "io-webdav",
31//!     "/dav/addressbooks/contacts/",
32//!     "alice",
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    rfc4918::{
60        WebdavAuth,
61        delete::Delete,
62        send::{SendError, SendOk},
63    },
64    rfc6352::card::join_path,
65};
66
67/// Coroutine that deletes a card.
68#[derive(Debug)]
69pub struct DeleteCard {
70    state: State,
71}
72
73impl DeleteCard {
74    /// Builds a new `delete-card` coroutine. `card_uri` is the resource
75    /// name as the server returned it (`CardRef::uri`).
76    pub fn new(
77        base_url: &Url,
78        auth: &WebdavAuth,
79        user_agent: &str,
80        addressbook_path: &str,
81        card_uri: &str,
82        if_match: Option<&str>,
83    ) -> Self {
84        let path = join_path(addressbook_path, card_uri);
85        Self {
86            state: State::Delete(Delete::new(base_url, auth, user_agent, &path, if_match)),
87        }
88    }
89}
90
91impl WebdavCoroutine for DeleteCard {
92    type Yield = WebdavYield;
93    type Return = Result<SendOk<Vec<u8>>, SendError>;
94
95    fn resume(&mut self, arg: Option<&[u8]>) -> WebdavCoroutineState<Self::Yield, Self::Return> {
96        trace!("sending request");
97        match &mut self.state {
98            State::Delete(delete) => delete.resume(arg),
99        }
100    }
101}
102
103#[derive(Debug)]
104enum State {
105    Delete(Delete),
106}