diff --git a/core/src/layers/complete.rs b/core/src/layers/complete.rs index 12ef4be30ce1..69e1e7b83d90 100644 --- a/core/src/layers/complete.rs +++ b/core/src/layers/complete.rs @@ -28,7 +28,6 @@ use async_trait::async_trait; use crate::raw::oio::BufferReader; use crate::raw::oio::FileReader; use crate::raw::oio::FlatLister; -use crate::raw::oio::FourWaysReader; use crate::raw::oio::LazyReader; use crate::raw::oio::PrefixLister; use crate::raw::oio::RangeReader; @@ -384,19 +383,19 @@ impl CompleteAccessor { // - If service can list_with_recursive, we can forward list to it directly. (_, true) => { let (rp, p) = self.inner.list(path, args).await?; - Ok((rp, CompleteLister::AlreadyComplete(p))) + Ok((rp, CompleteLister::One(p))) } // If recursive is true but service can't list_with_recursive (true, false) => { // Forward path that ends with / if path.ends_with('/') { let p = FlatLister::new(self.inner.clone(), path); - Ok((RpList::default(), CompleteLister::NeedFlat(p))) + Ok((RpList::default(), CompleteLister::Two(p))) } else { let parent = get_parent(path); let p = FlatLister::new(self.inner.clone(), parent); let p = PrefixLister::new(p, path); - Ok((RpList::default(), CompleteLister::Both(p))) + Ok((RpList::default(), CompleteLister::Four(p))) } } // If recursive and service doesn't support list_with_recursive, we need to handle @@ -405,12 +404,12 @@ impl CompleteAccessor { // Forward path that ends with / if path.ends_with('/') { let (rp, p) = self.inner.list(path, args).await?; - Ok((rp, CompleteLister::AlreadyComplete(p))) + Ok((rp, CompleteLister::One(p))) } else { let parent = get_parent(path); let (rp, p) = self.inner.list(parent, args).await?; let p = PrefixLister::new(p, path); - Ok((rp, CompleteLister::NeedPrefix(p))) + Ok((rp, CompleteLister::Three(p))) } } } @@ -432,19 +431,19 @@ impl CompleteAccessor { // - If service can list_with_recursive, we can forward list to it directly. (_, true) => { let (rp, p) = self.inner.blocking_list(path, args)?; - Ok((rp, CompleteLister::AlreadyComplete(p))) + Ok((rp, CompleteLister::One(p))) } // If recursive is true but service can't list_with_recursive (true, false) => { // Forward path that ends with / if path.ends_with('/') { let p = FlatLister::new(self.inner.clone(), path); - Ok((RpList::default(), CompleteLister::NeedFlat(p))) + Ok((RpList::default(), CompleteLister::Two(p))) } else { let parent = get_parent(path); let p = FlatLister::new(self.inner.clone(), parent); let p = PrefixLister::new(p, path); - Ok((RpList::default(), CompleteLister::Both(p))) + Ok((RpList::default(), CompleteLister::Four(p))) } } // If recursive and service doesn't support list_with_recursive, we need to handle @@ -453,12 +452,12 @@ impl CompleteAccessor { // Forward path that ends with / if path.ends_with('/') { let (rp, p) = self.inner.blocking_list(path, args)?; - Ok((rp, CompleteLister::AlreadyComplete(p))) + Ok((rp, CompleteLister::One(p))) } else { let parent = get_parent(path); let (rp, p) = self.inner.blocking_list(parent, args)?; let p = PrefixLister::new(p, path); - Ok((rp, CompleteLister::NeedPrefix(p))) + Ok((rp, CompleteLister::Three(p))) } } } @@ -676,53 +675,15 @@ impl LayeredAccessor for CompleteAccessor { pub type CompleteReader = TwoWays, BufferReader>>; -type InnerCompleteReader = FourWaysReader< +type InnerCompleteReader = FourWays< LazyReader, FileReader, RangeReader, StreamableReader>, >; -pub enum CompleteLister { - AlreadyComplete(P), - NeedFlat(FlatLister, P>), - NeedPrefix(PrefixLister

), - Both(PrefixLister, P>>), -} - -impl oio::List for CompleteLister -where - A: Accessor, - P: oio::List, -{ - fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { - use CompleteLister::*; - - match self { - AlreadyComplete(p) => p.poll_next(cx), - NeedFlat(p) => p.poll_next(cx), - NeedPrefix(p) => p.poll_next(cx), - Both(p) => p.poll_next(cx), - } - } -} - -impl oio::BlockingList for CompleteLister -where - A: Accessor, - P: oio::BlockingList, -{ - fn next(&mut self) -> Result> { - use CompleteLister::*; - - match self { - AlreadyComplete(p) => p.next(), - NeedFlat(p) => p.next(), - NeedPrefix(p) => p.next(), - Both(p) => p.next(), - } - } -} +pub type CompleteLister = + FourWays, P>, PrefixLister

, PrefixLister, P>>>; pub struct CompleteWriter { inner: Option, diff --git a/core/src/raw/enum_utils.rs b/core/src/raw/enum_utils.rs index 8728ea65be28..f2b2625b003c 100644 --- a/core/src/raw/enum_utils.rs +++ b/core/src/raw/enum_utils.rs @@ -15,15 +15,39 @@ // specific language governing permissions and limitations // under the License. +//! [`type_alias_impl_trait`](https://github.com/rust-lang/rust/issues/63063) is not stable yet. +//! So we can't write the following code: +//! +//! ```txt +//! impl Accessor for S3Backend { +//! type Writer = impl oio::Write; +//! } +//! ``` +//! +//! Which means we have to write the type directly like: +//! +//! ```txt +//! impl Accessor for OssBackend { +//! type Writer = raw::TwoWays< +//! oio::MultipartUploadWriter, +//! oio::AppendObjectWriter, +//! >; +//! } +//! ``` +//! +//! This module is used to provide some enums for the above code. We should remove this module once +//! type_alias_impl_trait has been stabilized. + +use bytes::Bytes; use std::io::SeekFrom; use std::task::{Context, Poll}; use crate::raw::*; use crate::*; -/// TwoWays is used to implement [`Read`] or [`Writer`] based on two ways. +/// TwoWays is used to implement traits that based on two ways. /// -/// Users can wrap two different readers/writers together. +/// Users can wrap two different trait types together. pub enum TwoWays { /// The first type for the [`TwoWays`]. One(ONE), @@ -34,22 +58,22 @@ pub enum TwoWays { impl oio::Read for TwoWays { fn poll_read(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll> { match self { - Self::One(one) => one.poll_read(cx, buf), - Self::Two(two) => two.poll_read(cx, buf), + Self::One(v) => v.poll_read(cx, buf), + Self::Two(v) => v.poll_read(cx, buf), } } fn poll_seek(&mut self, cx: &mut Context<'_>, pos: SeekFrom) -> Poll> { match self { - Self::One(one) => one.poll_seek(cx, pos), - Self::Two(two) => two.poll_seek(cx, pos), + Self::One(v) => v.poll_seek(cx, pos), + Self::Two(v) => v.poll_seek(cx, pos), } } - fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { + fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { match self { - Self::One(one) => one.poll_next(cx), - Self::Two(two) => two.poll_next(cx), + Self::One(v) => v.poll_next(cx), + Self::Two(v) => v.poll_next(cx), } } } @@ -57,22 +81,22 @@ impl oio::Read for TwoWays { impl oio::BlockingRead for TwoWays { fn read(&mut self, buf: &mut [u8]) -> Result { match self { - Self::One(one) => one.read(buf), - Self::Two(two) => two.read(buf), + Self::One(v) => v.read(buf), + Self::Two(v) => v.read(buf), } } fn seek(&mut self, pos: SeekFrom) -> Result { match self { - Self::One(one) => one.seek(pos), - Self::Two(two) => two.seek(pos), + Self::One(v) => v.seek(pos), + Self::Two(v) => v.seek(pos), } } - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option> { match self { - Self::One(one) => one.next(), - Self::Two(two) => two.next(), + Self::One(v) => v.next(), + Self::Two(v) => v.next(), } } } @@ -80,22 +104,234 @@ impl oio::BlockingRead for TwoWa impl oio::Write for TwoWays { fn poll_write(&mut self, cx: &mut Context<'_>, bs: &dyn oio::WriteBuf) -> Poll> { match self { - Self::One(one) => one.poll_write(cx, bs), - Self::Two(two) => two.poll_write(cx, bs), + Self::One(v) => v.poll_write(cx, bs), + Self::Two(v) => v.poll_write(cx, bs), } } fn poll_close(&mut self, cx: &mut Context<'_>) -> Poll> { match self { - Self::One(one) => one.poll_close(cx), - Self::Two(two) => two.poll_close(cx), + Self::One(v) => v.poll_close(cx), + Self::Two(v) => v.poll_close(cx), } } fn poll_abort(&mut self, cx: &mut Context<'_>) -> Poll> { match self { - Self::One(one) => one.poll_abort(cx), - Self::Two(two) => two.poll_abort(cx), + Self::One(v) => v.poll_abort(cx), + Self::Two(v) => v.poll_abort(cx), + } + } +} + +/// ThreeWays is used to implement traits that based on three ways. +/// +/// Users can wrap three different trait types together. +pub enum ThreeWays { + /// The first type for the [`ThreeWays`]. + One(ONE), + /// The second type for the [`ThreeWays`]. + Two(TWO), + /// The third type for the [`ThreeWays`]. + Three(THREE), +} + +impl oio::Read for ThreeWays { + fn poll_read(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll> { + match self { + Self::One(v) => v.poll_read(cx, buf), + Self::Two(v) => v.poll_read(cx, buf), + Self::Three(v) => v.poll_read(cx, buf), + } + } + + fn poll_seek(&mut self, cx: &mut Context<'_>, pos: SeekFrom) -> Poll> { + match self { + Self::One(v) => v.poll_seek(cx, pos), + Self::Two(v) => v.poll_seek(cx, pos), + Self::Three(v) => v.poll_seek(cx, pos), + } + } + + fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { + match self { + Self::One(v) => v.poll_next(cx), + Self::Two(v) => v.poll_next(cx), + Self::Three(v) => v.poll_next(cx), + } + } +} + +impl oio::BlockingRead + for ThreeWays +{ + fn read(&mut self, buf: &mut [u8]) -> Result { + match self { + Self::One(v) => v.read(buf), + Self::Two(v) => v.read(buf), + Self::Three(v) => v.read(buf), + } + } + + fn seek(&mut self, pos: SeekFrom) -> Result { + match self { + Self::One(v) => v.seek(pos), + Self::Two(v) => v.seek(pos), + Self::Three(v) => v.seek(pos), + } + } + + fn next(&mut self) -> Option> { + match self { + Self::One(v) => v.next(), + Self::Two(v) => v.next(), + Self::Three(v) => v.next(), + } + } +} + +impl oio::Write + for ThreeWays +{ + fn poll_write(&mut self, cx: &mut Context<'_>, bs: &dyn oio::WriteBuf) -> Poll> { + match self { + Self::One(v) => v.poll_write(cx, bs), + Self::Two(v) => v.poll_write(cx, bs), + Self::Three(v) => v.poll_write(cx, bs), + } + } + + fn poll_close(&mut self, cx: &mut Context<'_>) -> Poll> { + match self { + Self::One(v) => v.poll_close(cx), + Self::Two(v) => v.poll_close(cx), + Self::Three(v) => v.poll_close(cx), + } + } + + fn poll_abort(&mut self, cx: &mut Context<'_>) -> Poll> { + match self { + Self::One(v) => v.poll_abort(cx), + Self::Two(v) => v.poll_abort(cx), + Self::Three(v) => v.poll_abort(cx), + } + } +} + +/// FourWays is used to implement traits that based on four ways. +/// +/// Users can wrap four different trait types together. +pub enum FourWays { + /// The first type for the [`FourWays`]. + One(ONE), + /// The second type for the [`FourWays`]. + Two(TWO), + /// The third type for the [`FourWays`]. + Three(THREE), + /// The fourth type for the [`FourWays`]. + Four(FOUR), +} + +impl oio::Read for FourWays +where + ONE: oio::Read, + TWO: oio::Read, + THREE: oio::Read, + FOUR: oio::Read, +{ + fn poll_read(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll> { + match self { + Self::One(v) => v.poll_read(cx, buf), + Self::Two(v) => v.poll_read(cx, buf), + Self::Three(v) => v.poll_read(cx, buf), + Self::Four(v) => v.poll_read(cx, buf), + } + } + + fn poll_seek(&mut self, cx: &mut Context<'_>, pos: SeekFrom) -> Poll> { + match self { + Self::One(v) => v.poll_seek(cx, pos), + Self::Two(v) => v.poll_seek(cx, pos), + Self::Three(v) => v.poll_seek(cx, pos), + Self::Four(v) => v.poll_seek(cx, pos), + } + } + + fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { + match self { + Self::One(v) => v.poll_next(cx), + Self::Two(v) => v.poll_next(cx), + Self::Three(v) => v.poll_next(cx), + Self::Four(v) => v.poll_next(cx), + } + } +} + +impl oio::BlockingRead for FourWays +where + ONE: oio::BlockingRead, + TWO: oio::BlockingRead, + THREE: oio::BlockingRead, + FOUR: oio::BlockingRead, +{ + fn read(&mut self, buf: &mut [u8]) -> Result { + match self { + Self::One(v) => v.read(buf), + Self::Two(v) => v.read(buf), + Self::Three(v) => v.read(buf), + Self::Four(v) => v.read(buf), + } + } + + fn seek(&mut self, pos: SeekFrom) -> Result { + match self { + Self::One(v) => v.seek(pos), + Self::Two(v) => v.seek(pos), + Self::Three(v) => v.seek(pos), + Self::Four(v) => v.seek(pos), + } + } + + fn next(&mut self) -> Option> { + match self { + Self::One(v) => v.next(), + Self::Two(v) => v.next(), + Self::Three(v) => v.next(), + Self::Four(v) => v.next(), + } + } +} + +impl oio::List for FourWays +where + ONE: oio::List, + TWO: oio::List, + THREE: oio::List, + FOUR: oio::List, +{ + fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { + match self { + Self::One(v) => v.poll_next(cx), + Self::Two(v) => v.poll_next(cx), + Self::Three(v) => v.poll_next(cx), + Self::Four(v) => v.poll_next(cx), + } + } +} + +impl oio::BlockingList for FourWays +where + ONE: oio::BlockingList, + TWO: oio::BlockingList, + THREE: oio::BlockingList, + FOUR: oio::BlockingList, +{ + fn next(&mut self) -> Result> { + match self { + Self::One(v) => v.next(), + Self::Two(v) => v.next(), + Self::Three(v) => v.next(), + Self::Four(v) => v.next(), } } } diff --git a/core/src/raw/mod.rs b/core/src/raw/mod.rs index 99a3d1d4f971..ee8feac2608d 100644 --- a/core/src/raw/mod.rs +++ b/core/src/raw/mod.rs @@ -66,11 +66,11 @@ mod futures_util; pub use futures_util::BoxedFuture; pub use futures_util::ConcurrentFutures; +mod enum_utils; +pub use enum_utils::*; + // Expose as a pub mod to avoid confusing. pub mod adapters; pub mod oio; #[cfg(feature = "tests")] pub mod tests; - -mod enum_utils; -pub use enum_utils::TwoWays; diff --git a/core/src/raw/oio/read/compose_read.rs b/core/src/raw/oio/read/compose_read.rs deleted file mode 100644 index ccf350f27a0d..000000000000 --- a/core/src/raw/oio/read/compose_read.rs +++ /dev/null @@ -1,102 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -use std::io::SeekFrom; -use std::task::{Context, Poll}; - -use crate::raw::*; -use crate::*; - -/// FourWaysReader is used to implement [`Read`] based on four ways. -/// -/// Users can wrap four different readers together. -pub enum FourWaysReader { - /// The first type for the [`FourWaysReader`]. - One(ONE), - /// The second type for the [`FourWaysReader`]. - Two(TWO), - /// The third type for the [`FourWaysReader`]. - Three(THREE), - /// The fourth type for the [`FourWaysReader`]. - Four(FOUR), -} - -impl oio::Read - for FourWaysReader -{ - fn poll_read(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll> { - match self { - Self::One(one) => one.poll_read(cx, buf), - Self::Two(two) => two.poll_read(cx, buf), - Self::Three(three) => three.poll_read(cx, buf), - Self::Four(four) => four.poll_read(cx, buf), - } - } - - fn poll_seek(&mut self, cx: &mut Context<'_>, pos: SeekFrom) -> Poll> { - match self { - Self::One(one) => one.poll_seek(cx, pos), - Self::Two(two) => two.poll_seek(cx, pos), - Self::Three(three) => three.poll_seek(cx, pos), - Self::Four(four) => four.poll_seek(cx, pos), - } - } - - fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>> { - match self { - Self::One(one) => one.poll_next(cx), - Self::Two(two) => two.poll_next(cx), - Self::Three(three) => three.poll_next(cx), - Self::Four(four) => four.poll_next(cx), - } - } -} - -impl< - ONE: oio::BlockingRead, - TWO: oio::BlockingRead, - THREE: oio::BlockingRead, - FOUR: oio::BlockingRead, - > oio::BlockingRead for FourWaysReader -{ - fn read(&mut self, buf: &mut [u8]) -> Result { - match self { - Self::One(one) => one.read(buf), - Self::Two(two) => two.read(buf), - Self::Three(three) => three.read(buf), - Self::Four(four) => four.read(buf), - } - } - - fn seek(&mut self, pos: SeekFrom) -> Result { - match self { - Self::One(one) => one.seek(pos), - Self::Two(two) => two.seek(pos), - Self::Three(three) => three.seek(pos), - Self::Four(four) => four.seek(pos), - } - } - - fn next(&mut self) -> Option> { - match self { - Self::One(one) => one.next(), - Self::Two(two) => two.next(), - Self::Three(three) => three.next(), - Self::Four(four) => four.next(), - } - } -} diff --git a/core/src/raw/oio/read/mod.rs b/core/src/raw/oio/read/mod.rs index 2efe14a6d01a..d0edf682dc4c 100644 --- a/core/src/raw/oio/read/mod.rs +++ b/core/src/raw/oio/read/mod.rs @@ -51,6 +51,3 @@ pub use lazy_read::LazyReader; mod buffer_reader; pub use buffer_reader::BufferReader; - -mod compose_read; -pub use compose_read::FourWaysReader; diff --git a/core/src/raw/oio/write/compose_write.rs b/core/src/raw/oio/write/compose_write.rs deleted file mode 100644 index 78b8198951c2..000000000000 --- a/core/src/raw/oio/write/compose_write.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//! [`type_alias_impl_trait`](https://github.com/rust-lang/rust/issues/63063) is not stable yet. -//! So we can't write the following code: -//! -//! ```txt -//! impl Accessor for S3Backend { -//! type Writer = impl oio::Write; -//! } -//! ``` -//! -//! Which means we have to write the type directly like: -//! -//! ```txt -//! impl Accessor for OssBackend { -//! type Writer = raw::TwoWays< -//! oio::MultipartUploadWriter, -//! oio::AppendObjectWriter, -//! >; -//! } -//! ``` -//! -//! This module is used to provide some enums for the above code. We should remove this module once -//! type_alias_impl_trait has been stabilized. - -use std::task::Context; -use std::task::Poll; - -use crate::raw::*; -use crate::*; - -/// ThreeWaysWriter is used to implement [`Write`] based on three ways. -/// -/// Users can wrap three different writers together. -pub enum ThreeWaysWriter { - /// The first type for the [`ThreeWaysWriter`]. - One(ONE), - /// The second type for the [`ThreeWaysWriter`]. - Two(TWO), - /// The third type for the [`ThreeWaysWriter`]. - Three(THREE), -} - -impl oio::Write - for ThreeWaysWriter -{ - fn poll_write(&mut self, cx: &mut Context<'_>, bs: &dyn oio::WriteBuf) -> Poll> { - match self { - Self::One(one) => one.poll_write(cx, bs), - Self::Two(two) => two.poll_write(cx, bs), - Self::Three(three) => three.poll_write(cx, bs), - } - } - - fn poll_close(&mut self, cx: &mut Context<'_>) -> Poll> { - match self { - Self::One(one) => one.poll_close(cx), - Self::Two(two) => two.poll_close(cx), - Self::Three(three) => three.poll_close(cx), - } - } - - fn poll_abort(&mut self, cx: &mut Context<'_>) -> Poll> { - match self { - Self::One(one) => one.poll_abort(cx), - Self::Two(two) => two.poll_abort(cx), - Self::Three(three) => three.poll_abort(cx), - } - } -} diff --git a/core/src/raw/oio/write/mod.rs b/core/src/raw/oio/write/mod.rs index 58026a1edd7b..540d8d009783 100644 --- a/core/src/raw/oio/write/mod.rs +++ b/core/src/raw/oio/write/mod.rs @@ -23,9 +23,6 @@ pub use api::WriteExt; pub use api::WriteOperation; pub use api::Writer; -mod compose_write; -pub use compose_write::ThreeWaysWriter; - mod multipart_upload_write; pub use multipart_upload_write::MultipartUploadPart; pub use multipart_upload_write::MultipartUploadWrite;