tempest_rt/fs/
remove_file.rs1use std::{
4 io,
5 marker::PhantomData,
6 mem::replace,
7 path::PathBuf,
8 pin::Pin,
9 task::{Context, Poll},
10};
11
12use tempest_io::{Io, OpHandle};
13
14use crate::context::{current_io, get_op_handle};
15
16enum RemoveFileState {
17 NeedsSubmit {
18 path: PathBuf,
19 handle: Option<OpHandle>,
20 },
21 InFlight {
22 handle: OpHandle,
23 },
24 Done,
25}
26
27#[must_use = "futures do nothing unless awaited"]
29pub struct RemoveFile<I: Io> {
30 state: RemoveFileState,
31 _marker: PhantomData<fn() -> I>,
33}
34
35pub fn remove_file<I: Io>(path: PathBuf) -> RemoveFile<I> {
37 RemoveFile {
38 state: RemoveFileState::NeedsSubmit { path, handle: None },
39 _marker: PhantomData,
40 }
41}
42
43impl<I: Io> Unpin for RemoveFile<I> {}
45
46impl<I: Io> Future for RemoveFile<I> {
47 type Output = io::Result<()>;
48
49 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
50 let this = self.get_mut();
51
52 match replace(&mut this.state, RemoveFileState::Done) {
53 RemoveFileState::NeedsSubmit { path, handle } => {
54 let handle = handle.unwrap_or_else(|| unsafe { get_op_handle(cx) });
55
56 let io = unsafe { current_io::<I>() };
58 match io.remove(&path, handle) {
59 Ok(()) => {
60 this.state = RemoveFileState::InFlight { handle };
61 Poll::Pending
62 }
63 Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
64 this.state = RemoveFileState::NeedsSubmit {
66 path,
67 handle: Some(handle),
68 };
69 cx.waker().wake_by_ref();
70 Poll::Pending
71 }
72 Err(e) => Poll::Ready(Err(e)),
73 }
74 }
75 RemoveFileState::InFlight { handle } => {
76 let io = unsafe { current_io::<I>() };
78 match io.get_cqe(handle).transpose()? {
79 Some(_) => Poll::Ready(Ok(())),
80 None => {
81 this.state = RemoveFileState::InFlight { handle };
82 Poll::Pending
83 }
84 }
85 }
86 RemoveFileState::Done => panic!("polled after completion"),
87 }
88 }
89}