Skip to main content

opendal_core/raw/
enum_utils.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
18//! [`type_alias_impl_trait`](https://github.com/rust-lang/rust/issues/63063) is not stable yet.
19//! So we can't write the following code:
20//!
21//! ```txt
22//! impl Service for S3Backend {
23//!     fn write(...) -> Result<oio::Writer>;
24//! }
25//! ```
26//!
27//! Which means we have to write the type directly like:
28//!
29//! ```txt
30//! impl Service for OssBackend {
31//!     let writer = raw::TwoWays<
32//!         oio::MultipartWriter<OssWriter>,
33//!         oio::AppendWriter<OssWriter>,
34//!     >;
35//! }
36//! ```
37//!
38//! This module is used to provide some enums for the above code. We should remove this module once
39//! type_alias_impl_trait has been stabilized.
40
41use crate::raw::*;
42use crate::*;
43
44/// TwoWays is used to implement traits that based on two ways.
45///
46/// Users can wrap two different trait types together.
47pub enum TwoWays<ONE, TWO> {
48    /// The first type for the [`TwoWays`].
49    One(ONE),
50    /// The second type for the [`TwoWays`].
51    Two(TWO),
52}
53
54impl<ONE: oio::ReadStream, TWO: oio::ReadStream> oio::ReadStream for TwoWays<ONE, TWO> {
55    async fn read(&mut self) -> Result<Buffer> {
56        match self {
57            TwoWays::One(v) => v.read().await,
58            TwoWays::Two(v) => v.read().await,
59        }
60    }
61}
62
63impl<ONE: oio::Write, TWO: oio::Write> oio::Write for TwoWays<ONE, TWO> {
64    async fn write(&mut self, bs: Buffer) -> Result<()> {
65        match self {
66            Self::One(v) => v.write(bs).await,
67            Self::Two(v) => v.write(bs).await,
68        }
69    }
70
71    async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
72        match self {
73            Self::One(v) => v.copy_from(path, args, range).await,
74            Self::Two(v) => v.copy_from(path, args, range).await,
75        }
76    }
77
78    async fn close(&mut self) -> Result<Metadata> {
79        match self {
80            Self::One(v) => v.close().await,
81            Self::Two(v) => v.close().await,
82        }
83    }
84
85    async fn abort(&mut self) -> Result<()> {
86        match self {
87            Self::One(v) => v.abort().await,
88            Self::Two(v) => v.abort().await,
89        }
90    }
91}
92
93impl<ONE: oio::Copy, TWO: oio::Copy> oio::Copy for TwoWays<ONE, TWO> {
94    async fn next(&mut self) -> Result<Option<usize>> {
95        match self {
96            Self::One(v) => v.next().await,
97            Self::Two(v) => v.next().await,
98        }
99    }
100
101    async fn close(&mut self) -> Result<Metadata> {
102        match self {
103            Self::One(v) => v.close().await,
104            Self::Two(v) => v.close().await,
105        }
106    }
107
108    async fn abort(&mut self) -> Result<()> {
109        match self {
110            Self::One(v) => v.abort().await,
111            Self::Two(v) => v.abort().await,
112        }
113    }
114}
115
116impl<ONE: oio::List, TWO: oio::List> oio::List for TwoWays<ONE, TWO> {
117    async fn next(&mut self) -> Result<Option<oio::Entry>> {
118        match self {
119            Self::One(v) => v.next().await,
120            Self::Two(v) => v.next().await,
121        }
122    }
123}
124
125/// ThreeWays is used to implement traits that based on three ways.
126///
127/// Users can wrap three different trait types together.
128pub enum ThreeWays<ONE, TWO, THREE> {
129    /// The first type for the [`ThreeWays`].
130    One(ONE),
131    /// The second type for the [`ThreeWays`].
132    Two(TWO),
133    /// The third type for the [`ThreeWays`].
134    Three(THREE),
135}
136
137impl<ONE: oio::ReadStream, TWO: oio::ReadStream, THREE: oio::ReadStream> oio::ReadStream
138    for ThreeWays<ONE, TWO, THREE>
139{
140    async fn read(&mut self) -> Result<Buffer> {
141        match self {
142            ThreeWays::One(v) => v.read().await,
143            ThreeWays::Two(v) => v.read().await,
144            ThreeWays::Three(v) => v.read().await,
145        }
146    }
147}
148
149impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
150    for ThreeWays<ONE, TWO, THREE>
151{
152    async fn write(&mut self, bs: Buffer) -> Result<()> {
153        match self {
154            Self::One(v) => v.write(bs).await,
155            Self::Two(v) => v.write(bs).await,
156            Self::Three(v) => v.write(bs).await,
157        }
158    }
159
160    async fn close(&mut self) -> Result<Metadata> {
161        match self {
162            Self::One(v) => v.close().await,
163            Self::Two(v) => v.close().await,
164            Self::Three(v) => v.close().await,
165        }
166    }
167
168    async fn abort(&mut self) -> Result<()> {
169        match self {
170            Self::One(v) => v.abort().await,
171            Self::Two(v) => v.abort().await,
172            Self::Three(v) => v.abort().await,
173        }
174    }
175}
176
177impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
178    async fn next(&mut self) -> Result<Option<oio::Entry>> {
179        match self {
180            Self::One(v) => v.next().await,
181            Self::Two(v) => v.next().await,
182            Self::Three(v) => v.next().await,
183        }
184    }
185}
186
187/// FourWays is used to implement traits that based on four ways.
188///
189/// Users can wrap four different trait types together.
190pub enum FourWays<ONE, TWO, THREE, FOUR> {
191    /// The first type for the [`FourWays`].
192    One(ONE),
193    /// The second type for the [`FourWays`].
194    Two(TWO),
195    /// The third type for the [`FourWays`].
196    Three(THREE),
197    /// The fourth type for the [`FourWays`].
198    Four(FOUR),
199}
200
201impl<ONE, TWO, THREE, FOUR> oio::ReadStream for FourWays<ONE, TWO, THREE, FOUR>
202where
203    ONE: oio::ReadStream,
204    TWO: oio::ReadStream,
205    THREE: oio::ReadStream,
206    FOUR: oio::ReadStream,
207{
208    async fn read(&mut self) -> Result<Buffer> {
209        match self {
210            FourWays::One(v) => v.read().await,
211            FourWays::Two(v) => v.read().await,
212            FourWays::Three(v) => v.read().await,
213            FourWays::Four(v) => v.read().await,
214        }
215    }
216}
217
218impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
219where
220    ONE: oio::List,
221    TWO: oio::List,
222    THREE: oio::List,
223    FOUR: oio::List,
224{
225    async fn next(&mut self) -> Result<Option<oio::Entry>> {
226        match self {
227            Self::One(v) => v.next().await,
228            Self::Two(v) => v.next().await,
229            Self::Three(v) => v.next().await,
230            Self::Four(v) => v.next().await,
231        }
232    }
233}