opendal/raw/oio/delete/api.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::raw::{BoxedFuture, MaybeSend, OpDelete};
19use crate::*;
20use std::future::Future;
21use std::ops::DerefMut;
22
23/// Deleter is a type erased [`Delete`]
24pub type Deleter = Box<dyn DeleteDyn>;
25
26/// The Delete trait defines interfaces for performing deletion operations.
27pub trait Delete: Unpin + Send + Sync {
28 /// Requests deletion of a resource at the specified path with optional arguments
29 ///
30 /// # Parameters
31 /// - `path`: The path of the resource to delete
32 /// - `args`: Additional arguments for the delete operation
33 ///
34 /// # Returns
35 /// - `Ok(())`: The deletion request has been successfully queued (does not guarantee actual deletion)
36 /// - `Err(err)`: An error occurred and the deletion request was not queued
37 ///
38 /// # Notes
39 /// This method just queue the delete request. The actual deletion will be
40 /// performed when `flush` is called.
41 fn delete(&mut self, path: &str, args: OpDelete) -> Result<()>;
42
43 /// Flushes the deletion queue to ensure queued deletions are executed
44 ///
45 /// # Returns
46 /// - `Ok(0)`: All queued deletions have been processed or the queue is empty.
47 /// - `Ok(count)`: The number of resources successfully deleted. Implementations should
48 /// return an error if the queue is non-empty but no resources were deleted
49 /// - `Err(err)`: An error occurred while performing the deletions
50 ///
51 /// # Notes
52 /// - This method is asynchronous and will wait for queued deletions to complete
53 fn flush(&mut self) -> impl Future<Output = Result<usize>> + MaybeSend;
54}
55
56impl Delete for () {
57 fn delete(&mut self, _: &str, _: OpDelete) -> Result<()> {
58 Err(Error::new(
59 ErrorKind::Unsupported,
60 "output deleter doesn't support delete",
61 ))
62 }
63
64 async fn flush(&mut self) -> Result<usize> {
65 Err(Error::new(
66 ErrorKind::Unsupported,
67 "output deleter doesn't support flush",
68 ))
69 }
70}
71
72/// The dyn version of [`Delete`]
73pub trait DeleteDyn: Unpin + Send + Sync {
74 /// The dyn version of [`Delete::delete`]
75 fn delete_dyn(&mut self, path: &str, args: OpDelete) -> Result<()>;
76
77 /// The dyn version of [`Delete::flush`]
78 fn flush_dyn(&mut self) -> BoxedFuture<Result<usize>>;
79}
80
81impl<T: Delete + ?Sized> DeleteDyn for T {
82 fn delete_dyn(&mut self, path: &str, args: OpDelete) -> Result<()> {
83 Delete::delete(self, path, args)
84 }
85
86 fn flush_dyn(&mut self) -> BoxedFuture<Result<usize>> {
87 Box::pin(self.flush())
88 }
89}
90
91impl<T: DeleteDyn + ?Sized> Delete for Box<T> {
92 fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
93 self.deref_mut().delete_dyn(path, args)
94 }
95
96 async fn flush(&mut self) -> Result<usize> {
97 self.deref_mut().flush_dyn().await
98 }
99}
100
101/// BlockingDeleter is a type erased [`BlockingDelete`]
102pub type BlockingDeleter = Box<dyn BlockingDelete>;
103
104/// BlockingDelete is the trait to perform delete operations.
105pub trait BlockingDelete: Send + Sync + 'static {
106 /// Delete given path with optional arguments.
107 ///
108 /// # Behavior
109 ///
110 /// - `Ok(())` means the path has been queued for deletion.
111 /// - `Err(err)` means error happens and no deletion has been queued.
112 fn delete(&mut self, path: &str, args: OpDelete) -> Result<()>;
113
114 /// Flushes the deletion queue to ensure queued deletions are executed
115 ///
116 /// # Returns
117 /// - `Ok(0)`: All queued deletions have been processed or the queue is empty.
118 /// - `Ok(count)`: The number of resources successfully deleted. Implementations should
119 /// return an error if the queue is non-empty but no resources were deleted
120 /// - `Err(err)`: An error occurred while performing the deletions
121 fn flush(&mut self) -> Result<usize>;
122}
123
124impl BlockingDelete for () {
125 fn delete(&mut self, _: &str, _: OpDelete) -> Result<()> {
126 Err(Error::new(
127 ErrorKind::Unsupported,
128 "output deleter doesn't support delete",
129 ))
130 }
131
132 fn flush(&mut self) -> Result<usize> {
133 Err(Error::new(
134 ErrorKind::Unsupported,
135 "output deleter doesn't support flush",
136 ))
137 }
138}
139
140/// `Box<dyn BlockingDelete>` won't implement `BlockingDelete` automatically.
141///
142/// To make BlockingWriter work as expected, we must add this impl.
143impl<T: BlockingDelete + ?Sized> BlockingDelete for Box<T> {
144 fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
145 (**self).delete(path, args)
146 }
147
148 fn flush(&mut self) -> Result<usize> {
149 (**self).flush()
150 }
151}