opendal/raw/oio/write/
one_shot_write.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 std::future::Future;
19
20use crate::raw::*;
21use crate::*;
22
23/// OneShotWrite is used to implement [`oio::Write`] based on one shot operation.
24/// By implementing OneShotWrite, services don't need to care about the details.
25///
26/// For example, S3 `PUT Object` and fs `write_all`.
27///
28/// The layout after adopting [`OneShotWrite`]:
29pub trait OneShotWrite: Send + Sync + Unpin + 'static {
30    /// write_once write all data at once.
31    ///
32    /// Implementations should make sure that the data is written correctly at once.
33    fn write_once(&self, bs: Buffer) -> impl Future<Output = Result<Metadata>> + MaybeSend;
34}
35
36/// OneShotWrite is used to implement [`oio::Write`] based on one shot.
37pub struct OneShotWriter<W: OneShotWrite> {
38    inner: W,
39    buffer: Option<Buffer>,
40}
41
42impl<W: OneShotWrite> OneShotWriter<W> {
43    /// Create a new one shot writer.
44    pub fn new(inner: W) -> Self {
45        Self {
46            inner,
47            buffer: None,
48        }
49    }
50}
51
52impl<W: OneShotWrite> oio::Write for OneShotWriter<W> {
53    async fn write(&mut self, bs: Buffer) -> Result<()> {
54        match &self.buffer {
55            Some(_) => Err(Error::new(
56                ErrorKind::Unsupported,
57                "OneShotWriter doesn't support multiple write",
58            )),
59            None => {
60                self.buffer = Some(bs);
61                Ok(())
62            }
63        }
64    }
65
66    async fn close(&mut self) -> Result<Metadata> {
67        match self.buffer.clone() {
68            Some(bs) => self.inner.write_once(bs).await,
69            None => self.inner.write_once(Buffer::new()).await,
70        }
71    }
72
73    async fn abort(&mut self) -> Result<()> {
74        self.buffer = None;
75        Ok(())
76    }
77}