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 Access for S3Backend {
23//!     type Writer = impl oio::Write;
24//! }
25//! ```
26//!
27//! Which means we have to write the type directly like:
28//!
29//! ```txt
30//! impl Access for OssBackend {
31//!     type 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 close(&mut self) -> Result<Metadata> {
72        match self {
73            Self::One(v) => v.close().await,
74            Self::Two(v) => v.close().await,
75        }
76    }
77
78    async fn abort(&mut self) -> Result<()> {
79        match self {
80            Self::One(v) => v.abort().await,
81            Self::Two(v) => v.abort().await,
82        }
83    }
84}
85
86impl<ONE: oio::Copy, TWO: oio::Copy> oio::Copy for TwoWays<ONE, TWO> {
87    async fn next(&mut self) -> Result<Option<usize>> {
88        match self {
89            Self::One(v) => v.next().await,
90            Self::Two(v) => v.next().await,
91        }
92    }
93
94    async fn close(&mut self) -> Result<Metadata> {
95        match self {
96            Self::One(v) => v.close().await,
97            Self::Two(v) => v.close().await,
98        }
99    }
100
101    async fn abort(&mut self) -> Result<()> {
102        match self {
103            Self::One(v) => v.abort().await,
104            Self::Two(v) => v.abort().await,
105        }
106    }
107}
108
109impl<ONE: oio::List, TWO: oio::List> oio::List for TwoWays<ONE, TWO> {
110    async fn next(&mut self) -> Result<Option<oio::Entry>> {
111        match self {
112            Self::One(v) => v.next().await,
113            Self::Two(v) => v.next().await,
114        }
115    }
116}
117
118/// ThreeWays is used to implement traits that based on three ways.
119///
120/// Users can wrap three different trait types together.
121pub enum ThreeWays<ONE, TWO, THREE> {
122    /// The first type for the [`ThreeWays`].
123    One(ONE),
124    /// The second type for the [`ThreeWays`].
125    Two(TWO),
126    /// The third type for the [`ThreeWays`].
127    Three(THREE),
128}
129
130impl<ONE: oio::ReadStream, TWO: oio::ReadStream, THREE: oio::ReadStream> oio::ReadStream
131    for ThreeWays<ONE, TWO, THREE>
132{
133    async fn read(&mut self) -> Result<Buffer> {
134        match self {
135            ThreeWays::One(v) => v.read().await,
136            ThreeWays::Two(v) => v.read().await,
137            ThreeWays::Three(v) => v.read().await,
138        }
139    }
140}
141
142impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
143    for ThreeWays<ONE, TWO, THREE>
144{
145    async fn write(&mut self, bs: Buffer) -> Result<()> {
146        match self {
147            Self::One(v) => v.write(bs).await,
148            Self::Two(v) => v.write(bs).await,
149            Self::Three(v) => v.write(bs).await,
150        }
151    }
152
153    async fn close(&mut self) -> Result<Metadata> {
154        match self {
155            Self::One(v) => v.close().await,
156            Self::Two(v) => v.close().await,
157            Self::Three(v) => v.close().await,
158        }
159    }
160
161    async fn abort(&mut self) -> Result<()> {
162        match self {
163            Self::One(v) => v.abort().await,
164            Self::Two(v) => v.abort().await,
165            Self::Three(v) => v.abort().await,
166        }
167    }
168}
169
170impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
171    async fn next(&mut self) -> Result<Option<oio::Entry>> {
172        match self {
173            Self::One(v) => v.next().await,
174            Self::Two(v) => v.next().await,
175            Self::Three(v) => v.next().await,
176        }
177    }
178}
179
180/// FourWays is used to implement traits that based on four ways.
181///
182/// Users can wrap four different trait types together.
183pub enum FourWays<ONE, TWO, THREE, FOUR> {
184    /// The first type for the [`FourWays`].
185    One(ONE),
186    /// The second type for the [`FourWays`].
187    Two(TWO),
188    /// The third type for the [`FourWays`].
189    Three(THREE),
190    /// The fourth type for the [`FourWays`].
191    Four(FOUR),
192}
193
194impl<ONE, TWO, THREE, FOUR> oio::ReadStream for FourWays<ONE, TWO, THREE, FOUR>
195where
196    ONE: oio::ReadStream,
197    TWO: oio::ReadStream,
198    THREE: oio::ReadStream,
199    FOUR: oio::ReadStream,
200{
201    async fn read(&mut self) -> Result<Buffer> {
202        match self {
203            FourWays::One(v) => v.read().await,
204            FourWays::Two(v) => v.read().await,
205            FourWays::Three(v) => v.read().await,
206            FourWays::Four(v) => v.read().await,
207        }
208    }
209}
210
211impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
212where
213    ONE: oio::List,
214    TWO: oio::List,
215    THREE: oio::List,
216    FOUR: oio::List,
217{
218    async fn next(&mut self) -> Result<Option<oio::Entry>> {
219        match self {
220            Self::One(v) => v.next().await,
221            Self::Two(v) => v.next().await,
222            Self::Three(v) => v.next().await,
223            Self::Four(v) => v.next().await,
224        }
225    }
226}