Skip to main content

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}