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::Read, TWO: oio::Read> oio::Read 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::Read, TWO: oio::Read, THREE: oio::Read> oio::Read for ThreeWays<ONE, TWO, THREE> {
131    async fn read(&mut self) -> Result<Buffer> {
132        match self {
133            ThreeWays::One(v) => v.read().await,
134            ThreeWays::Two(v) => v.read().await,
135            ThreeWays::Three(v) => v.read().await,
136        }
137    }
138}
139
140impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
141    for ThreeWays<ONE, TWO, THREE>
142{
143    async fn write(&mut self, bs: Buffer) -> Result<()> {
144        match self {
145            Self::One(v) => v.write(bs).await,
146            Self::Two(v) => v.write(bs).await,
147            Self::Three(v) => v.write(bs).await,
148        }
149    }
150
151    async fn close(&mut self) -> Result<Metadata> {
152        match self {
153            Self::One(v) => v.close().await,
154            Self::Two(v) => v.close().await,
155            Self::Three(v) => v.close().await,
156        }
157    }
158
159    async fn abort(&mut self) -> Result<()> {
160        match self {
161            Self::One(v) => v.abort().await,
162            Self::Two(v) => v.abort().await,
163            Self::Three(v) => v.abort().await,
164        }
165    }
166}
167
168impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
169    async fn next(&mut self) -> Result<Option<oio::Entry>> {
170        match self {
171            Self::One(v) => v.next().await,
172            Self::Two(v) => v.next().await,
173            Self::Three(v) => v.next().await,
174        }
175    }
176}
177
178/// FourWays is used to implement traits that based on four ways.
179///
180/// Users can wrap four different trait types together.
181pub enum FourWays<ONE, TWO, THREE, FOUR> {
182    /// The first type for the [`FourWays`].
183    One(ONE),
184    /// The second type for the [`FourWays`].
185    Two(TWO),
186    /// The third type for the [`FourWays`].
187    Three(THREE),
188    /// The fourth type for the [`FourWays`].
189    Four(FOUR),
190}
191
192impl<ONE, TWO, THREE, FOUR> oio::Read for FourWays<ONE, TWO, THREE, FOUR>
193where
194    ONE: oio::Read,
195    TWO: oio::Read,
196    THREE: oio::Read,
197    FOUR: oio::Read,
198{
199    async fn read(&mut self) -> Result<Buffer> {
200        match self {
201            FourWays::One(v) => v.read().await,
202            FourWays::Two(v) => v.read().await,
203            FourWays::Three(v) => v.read().await,
204            FourWays::Four(v) => v.read().await,
205        }
206    }
207}
208
209impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
210where
211    ONE: oio::List,
212    TWO: oio::List,
213    THREE: oio::List,
214    FOUR: oio::List,
215{
216    async fn next(&mut self) -> Result<Option<oio::Entry>> {
217        match self {
218            Self::One(v) => v.next().await,
219            Self::Two(v) => v.next().await,
220            Self::Three(v) => v.next().await,
221            Self::Four(v) => v.next().await,
222        }
223    }
224}