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 abort(&mut self) -> Result<()> {
95        match self {
96            Self::One(v) => v.abort().await,
97            Self::Two(v) => v.abort().await,
98        }
99    }
100}
101
102impl<ONE: oio::List, TWO: oio::List> oio::List for TwoWays<ONE, TWO> {
103    async fn next(&mut self) -> Result<Option<oio::Entry>> {
104        match self {
105            Self::One(v) => v.next().await,
106            Self::Two(v) => v.next().await,
107        }
108    }
109}
110
111/// ThreeWays is used to implement traits that based on three ways.
112///
113/// Users can wrap three different trait types together.
114pub enum ThreeWays<ONE, TWO, THREE> {
115    /// The first type for the [`ThreeWays`].
116    One(ONE),
117    /// The second type for the [`ThreeWays`].
118    Two(TWO),
119    /// The third type for the [`ThreeWays`].
120    Three(THREE),
121}
122
123impl<ONE: oio::Read, TWO: oio::Read, THREE: oio::Read> oio::Read for ThreeWays<ONE, TWO, THREE> {
124    async fn read(&mut self) -> Result<Buffer> {
125        match self {
126            ThreeWays::One(v) => v.read().await,
127            ThreeWays::Two(v) => v.read().await,
128            ThreeWays::Three(v) => v.read().await,
129        }
130    }
131}
132
133impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
134    for ThreeWays<ONE, TWO, THREE>
135{
136    async fn write(&mut self, bs: Buffer) -> Result<()> {
137        match self {
138            Self::One(v) => v.write(bs).await,
139            Self::Two(v) => v.write(bs).await,
140            Self::Three(v) => v.write(bs).await,
141        }
142    }
143
144    async fn close(&mut self) -> Result<Metadata> {
145        match self {
146            Self::One(v) => v.close().await,
147            Self::Two(v) => v.close().await,
148            Self::Three(v) => v.close().await,
149        }
150    }
151
152    async fn abort(&mut self) -> Result<()> {
153        match self {
154            Self::One(v) => v.abort().await,
155            Self::Two(v) => v.abort().await,
156            Self::Three(v) => v.abort().await,
157        }
158    }
159}
160
161impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
162    async fn next(&mut self) -> Result<Option<oio::Entry>> {
163        match self {
164            Self::One(v) => v.next().await,
165            Self::Two(v) => v.next().await,
166            Self::Three(v) => v.next().await,
167        }
168    }
169}
170
171/// FourWays is used to implement traits that based on four ways.
172///
173/// Users can wrap four different trait types together.
174pub enum FourWays<ONE, TWO, THREE, FOUR> {
175    /// The first type for the [`FourWays`].
176    One(ONE),
177    /// The second type for the [`FourWays`].
178    Two(TWO),
179    /// The third type for the [`FourWays`].
180    Three(THREE),
181    /// The fourth type for the [`FourWays`].
182    Four(FOUR),
183}
184
185impl<ONE, TWO, THREE, FOUR> oio::Read for FourWays<ONE, TWO, THREE, FOUR>
186where
187    ONE: oio::Read,
188    TWO: oio::Read,
189    THREE: oio::Read,
190    FOUR: oio::Read,
191{
192    async fn read(&mut self) -> Result<Buffer> {
193        match self {
194            FourWays::One(v) => v.read().await,
195            FourWays::Two(v) => v.read().await,
196            FourWays::Three(v) => v.read().await,
197            FourWays::Four(v) => v.read().await,
198        }
199    }
200}
201
202impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
203where
204    ONE: oio::List,
205    TWO: oio::List,
206    THREE: oio::List,
207    FOUR: oio::List,
208{
209    async fn next(&mut self) -> Result<Option<oio::Entry>> {
210        match self {
211            Self::One(v) => v.next().await,
212            Self::Two(v) => v.next().await,
213            Self::Three(v) => v.next().await,
214            Self::Four(v) => v.next().await,
215        }
216    }
217}