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}