This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 87e98ef7ca feat(fs): expose the metadata for fs services (#5005)
87e98ef7ca is described below
commit 87e98ef7ca163ffde83c14b3b1f072dcafa56274
Author: WenjunMin <[email protected]>
AuthorDate: Wed Aug 14 13:18:53 2024 +0800
feat(fs): expose the metadata for fs services (#5005)
* fix(fs): expose the metadata for fs services
* fix
* fix comments
* clippy
* fix
* fix comments
* fix comments
---
core/src/services/fs/backend.rs | 8 ++--
core/src/services/fs/lister.rs | 88 ++++++++++++++++++++++++++++++-----------
2 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs
index 93bdd445ad..151e35aef6 100644
--- a/core/src/services/fs/backend.rs
+++ b/core/src/services/fs/backend.rs
@@ -353,7 +353,7 @@ impl Access for FsBackend {
}
}
- async fn list(&self, path: &str, _: OpList) -> Result<(RpList,
Self::Lister)> {
+ async fn list(&self, path: &str, arg: OpList) -> Result<(RpList,
Self::Lister)> {
let p = self.core.root.join(path.trim_end_matches('/'));
let f = match tokio::fs::read_dir(&p).await {
@@ -367,7 +367,7 @@ impl Access for FsBackend {
}
};
- let rd = FsLister::new(&self.core.root, f);
+ let rd = FsLister::new(&self.core.root, f, arg);
Ok((RpList::default(), Some(rd)))
}
@@ -523,7 +523,7 @@ impl Access for FsBackend {
}
}
- fn blocking_list(&self, path: &str, _: OpList) -> Result<(RpList,
Self::BlockingLister)> {
+ fn blocking_list(&self, path: &str, arg: OpList) -> Result<(RpList,
Self::BlockingLister)> {
let p = self.core.root.join(path.trim_end_matches('/'));
let f = match std::fs::read_dir(p) {
@@ -537,7 +537,7 @@ impl Access for FsBackend {
}
};
- let rd = FsLister::new(&self.core.root, f);
+ let rd = FsLister::new(&self.core.root, f, arg);
Ok((RpList::default(), Some(rd)))
}
diff --git a/core/src/services/fs/lister.rs b/core/src/services/fs/lister.rs
index eec0a4b8aa..229e7f7896 100644
--- a/core/src/services/fs/lister.rs
+++ b/core/src/services/fs/lister.rs
@@ -15,25 +15,27 @@
// specific language governing permissions and limitations
// under the License.
-use std::path::Path;
-use std::path::PathBuf;
-
use crate::raw::*;
-use crate::EntryMode;
use crate::Metadata;
use crate::Result;
+use crate::{EntryMode, Metakey};
+use std::path::Path;
+use std::path::PathBuf;
pub struct FsLister<P> {
root: PathBuf,
rd: P,
+
+ op: OpList,
}
impl<P> FsLister<P> {
- pub fn new(root: &Path, rd: P) -> Self {
+ pub fn new(root: &Path, rd: P, arg: OpList) -> Self {
Self {
root: root.to_owned(),
rd,
+ op: arg,
}
}
}
@@ -49,8 +51,6 @@ impl oio::List for FsLister<tokio::fs::ReadDir> {
return Ok(None);
};
- let ft = de.file_type().await.map_err(new_std_io_error)?;
-
let entry_path = de.path();
let rel_path = normalize_path(
&entry_path
@@ -60,16 +60,39 @@ impl oio::List for FsLister<tokio::fs::ReadDir> {
.replace('\\', "/"),
);
- let d = if ft.is_file() {
- oio::Entry::new(&rel_path, Metadata::new(EntryMode::FILE))
- } else if ft.is_dir() {
+ let default_meta = self.op.metakey() == Metakey::Mode;
+
+ let metadata = if default_meta {
+ let ft = de.file_type().await.map_err(new_std_io_error)?;
+ if ft.is_file() {
+ Metadata::new(EntryMode::FILE)
+ } else if ft.is_dir() {
+ Metadata::new(EntryMode::DIR)
+ } else {
+ Metadata::new(EntryMode::Unknown)
+ }
+ } else {
+ let fs_meta = de.metadata().await.map_err(new_std_io_error)?;
+ let mut meta = if fs_meta.file_type().is_file() {
+ Metadata::new(EntryMode::FILE)
+ } else if fs_meta.file_type().is_dir() {
+ Metadata::new(EntryMode::DIR)
+ } else {
+ Metadata::new(EntryMode::Unknown)
+ };
+ meta.set_content_length(fs_meta.len());
+
meta.set_last_modified(fs_meta.modified().map_err(new_std_io_error)?.into());
+ meta
+ };
+
+ let p = if metadata.is_dir() {
// Make sure we are returning the correct path.
- oio::Entry::new(&format!("{rel_path}/"),
Metadata::new(EntryMode::DIR))
+ &format!("{rel_path}/")
} else {
- oio::Entry::new(&rel_path, Metadata::new(EntryMode::Unknown))
+ &rel_path
};
- Ok(Some(d))
+ Ok(Some(oio::Entry::new(p, metadata)))
}
}
@@ -89,21 +112,38 @@ impl oio::BlockingList for FsLister<std::fs::ReadDir> {
.replace('\\', "/"),
);
- // On Windows and most Unix platforms this function is free
- // (no extra system calls needed), but some Unix platforms may
- // require the equivalent call to symlink_metadata to learn about
- // the target file type.
- let file_type = de.file_type().map_err(new_std_io_error)?;
+ let default_meta = self.op.metakey() == Metakey::Mode;
+
+ let metadata = if default_meta {
+ let ft = de.file_type().map_err(new_std_io_error)?;
+ if ft.is_file() {
+ Metadata::new(EntryMode::FILE)
+ } else if ft.is_dir() {
+ Metadata::new(EntryMode::DIR)
+ } else {
+ Metadata::new(EntryMode::Unknown)
+ }
+ } else {
+ let fs_meta = de.metadata().map_err(new_std_io_error)?;
+ let mut meta = if fs_meta.file_type().is_file() {
+ Metadata::new(EntryMode::FILE)
+ } else if fs_meta.file_type().is_dir() {
+ Metadata::new(EntryMode::DIR)
+ } else {
+ Metadata::new(EntryMode::Unknown)
+ };
+ meta.set_content_length(fs_meta.len());
+
meta.set_last_modified(fs_meta.modified().map_err(new_std_io_error)?.into());
+ meta
+ };
- let entry = if file_type.is_file() {
- oio::Entry::new(&rel_path, Metadata::new(EntryMode::FILE))
- } else if file_type.is_dir() {
+ let p = if metadata.is_dir() {
// Make sure we are returning the correct path.
- oio::Entry::new(&format!("{rel_path}/"),
Metadata::new(EntryMode::DIR))
+ &format!("{rel_path}/")
} else {
- oio::Entry::new(&rel_path, Metadata::new(EntryMode::Unknown))
+ &rel_path
};
- Ok(Some(entry))
+ Ok(Some(oio::Entry::new(p, metadata)))
}
}