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