opendal/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::BlockingRead, TWO: oio::BlockingRead> oio::BlockingRead for TwoWays<ONE, TWO> {
64    fn read(&mut self) -> Result<Buffer> {
65        match self {
66            Self::One(v) => v.read(),
67            Self::Two(v) => v.read(),
68        }
69    }
70}
71
72impl<ONE: oio::Write, TWO: oio::Write> oio::Write for TwoWays<ONE, TWO> {
73    async fn write(&mut self, bs: Buffer) -> Result<()> {
74        match self {
75            Self::One(v) => v.write(bs).await,
76            Self::Two(v) => v.write(bs).await,
77        }
78    }
79
80    async fn close(&mut self) -> Result<Metadata> {
81        match self {
82            Self::One(v) => v.close().await,
83            Self::Two(v) => v.close().await,
84        }
85    }
86
87    async fn abort(&mut self) -> Result<()> {
88        match self {
89            Self::One(v) => v.abort().await,
90            Self::Two(v) => v.abort().await,
91        }
92    }
93}
94
95impl<ONE: oio::List, TWO: oio::List> oio::List for TwoWays<ONE, TWO> {
96    async fn next(&mut self) -> Result<Option<oio::Entry>> {
97        match self {
98            Self::One(v) => v.next().await,
99            Self::Two(v) => v.next().await,
100        }
101    }
102}
103
104/// ThreeWays is used to implement traits that based on three ways.
105///
106/// Users can wrap three different trait types together.
107pub enum ThreeWays<ONE, TWO, THREE> {
108    /// The first type for the [`ThreeWays`].
109    One(ONE),
110    /// The second type for the [`ThreeWays`].
111    Two(TWO),
112    /// The third type for the [`ThreeWays`].
113    Three(THREE),
114}
115
116impl<ONE: oio::Read, TWO: oio::Read, THREE: oio::Read> oio::Read for ThreeWays<ONE, TWO, THREE> {
117    async fn read(&mut self) -> Result<Buffer> {
118        match self {
119            ThreeWays::One(v) => v.read().await,
120            ThreeWays::Two(v) => v.read().await,
121            ThreeWays::Three(v) => v.read().await,
122        }
123    }
124}
125
126impl<ONE: oio::BlockingRead, TWO: oio::BlockingRead, THREE: oio::BlockingRead> oio::BlockingRead
127    for ThreeWays<ONE, TWO, THREE>
128{
129    fn read(&mut self) -> Result<Buffer> {
130        match self {
131            Self::One(v) => v.read(),
132            Self::Two(v) => v.read(),
133            Self::Three(v) => v.read(),
134        }
135    }
136}
137
138impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
139    for ThreeWays<ONE, TWO, THREE>
140{
141    async fn write(&mut self, bs: Buffer) -> Result<()> {
142        match self {
143            Self::One(v) => v.write(bs).await,
144            Self::Two(v) => v.write(bs).await,
145            Self::Three(v) => v.write(bs).await,
146        }
147    }
148
149    async fn close(&mut self) -> Result<Metadata> {
150        match self {
151            Self::One(v) => v.close().await,
152            Self::Two(v) => v.close().await,
153            Self::Three(v) => v.close().await,
154        }
155    }
156
157    async fn abort(&mut self) -> Result<()> {
158        match self {
159            Self::One(v) => v.abort().await,
160            Self::Two(v) => v.abort().await,
161            Self::Three(v) => v.abort().await,
162        }
163    }
164}
165
166impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
167    async fn next(&mut self) -> Result<Option<oio::Entry>> {
168        match self {
169            Self::One(v) => v.next().await,
170            Self::Two(v) => v.next().await,
171            Self::Three(v) => v.next().await,
172        }
173    }
174}
175
176/// FourWays is used to implement traits that based on four ways.
177///
178/// Users can wrap four different trait types together.
179pub enum FourWays<ONE, TWO, THREE, FOUR> {
180    /// The first type for the [`FourWays`].
181    One(ONE),
182    /// The second type for the [`FourWays`].
183    Two(TWO),
184    /// The third type for the [`FourWays`].
185    Three(THREE),
186    /// The fourth type for the [`FourWays`].
187    Four(FOUR),
188}
189
190impl<ONE, TWO, THREE, FOUR> oio::Read for FourWays<ONE, TWO, THREE, FOUR>
191where
192    ONE: oio::Read,
193    TWO: oio::Read,
194    THREE: oio::Read,
195    FOUR: oio::Read,
196{
197    async fn read(&mut self) -> Result<Buffer> {
198        match self {
199            FourWays::One(v) => v.read().await,
200            FourWays::Two(v) => v.read().await,
201            FourWays::Three(v) => v.read().await,
202            FourWays::Four(v) => v.read().await,
203        }
204    }
205}
206
207impl<ONE, TWO, THREE, FOUR> oio::BlockingRead for FourWays<ONE, TWO, THREE, FOUR>
208where
209    ONE: oio::BlockingRead,
210    TWO: oio::BlockingRead,
211    THREE: oio::BlockingRead,
212    FOUR: oio::BlockingRead,
213{
214    fn read(&mut self) -> Result<Buffer> {
215        match self {
216            Self::One(v) => v.read(),
217            Self::Two(v) => v.read(),
218            Self::Three(v) => v.read(),
219            Self::Four(v) => v.read(),
220        }
221    }
222}
223
224impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
225where
226    ONE: oio::List,
227    TWO: oio::List,
228    THREE: oio::List,
229    FOUR: oio::List,
230{
231    async fn next(&mut self) -> Result<Option<oio::Entry>> {
232        match self {
233            Self::One(v) => v.next().await,
234            Self::Two(v) => v.next().await,
235            Self::Three(v) => v.next().await,
236            Self::Four(v) => v.next().await,
237        }
238    }
239}
240
241impl<ONE, TWO, THREE, FOUR> oio::BlockingList for FourWays<ONE, TWO, THREE, FOUR>
242where
243    ONE: oio::BlockingList,
244    TWO: oio::BlockingList,
245    THREE: oio::BlockingList,
246    FOUR: oio::BlockingList,
247{
248    fn next(&mut self) -> Result<Option<oio::Entry>> {
249        match self {
250            Self::One(v) => v.next(),
251            Self::Two(v) => v.next(),
252            Self::Three(v) => v.next(),
253            Self::Four(v) => v.next(),
254        }
255    }
256}