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}