Registered Users
@@ -43,7 +43,7 @@
{{#if ../sso_enabled}}
- {{sso_identifier}}
+ {{sso_identifier}}
|
{{/if}}
diff --git a/src/storage.rs b/src/storage.rs
deleted file mode 100644
index ada2a951..00000000
--- a/src/storage.rs
+++ /dev/null
@@ -1,297 +0,0 @@
-use std::sync::LazyLock;
-
-pub(crate) fn join_path(base: &str, child: &str) -> String {
- #[cfg(s3)]
- if s3::is_uri(base) {
- return s3::join_path(base, child);
- }
-
- let base = base.trim_end_matches('/');
- let child = child.trim_start_matches('/');
- if base.is_empty() {
- child.to_string()
- } else if child.is_empty() {
- base.to_string()
- } else {
- format!("{base}/{child}")
- }
-}
-
-pub(crate) fn with_extension(path: &str, extension: &str) -> String {
- let extension = extension.trim_start_matches('.');
-
- #[cfg(s3)]
- if s3::is_uri(path) {
- return s3::with_extension(path, extension);
- }
-
- format!("{path}.{extension}")
-}
-
-pub(crate) fn parent(path: &str) -> Option {
- #[cfg(s3)]
- if s3::is_uri(path) {
- return s3::parent(path);
- }
-
- std::path::Path::new(path).parent()?.to_str().map(ToString::to_string)
-}
-
-pub(crate) fn file_name(path: &str) -> Option {
- #[cfg(s3)]
- if s3::is_uri(path) {
- return s3::file_name(path);
- }
-
- std::path::Path::new(path).file_name()?.to_str().map(ToString::to_string)
-}
-
-pub(crate) fn is_fs_operator(operator: &opendal::Operator) -> bool {
- operator.info().scheme() == opendal::services::FS_SCHEME
-}
-
-pub(crate) fn operator_for_path(path: &str) -> Result {
- // Cache of previously built operators by path
- static OPERATORS_BY_PATH: LazyLock> =
- LazyLock::new(dashmap::DashMap::new);
-
- if let Some(operator) = OPERATORS_BY_PATH.get(path) {
- return Ok(operator.clone());
- }
-
- let operator = if path.starts_with("s3://") {
- #[cfg(not(s3))]
- return Err(opendal::Error::new(opendal::ErrorKind::ConfigInvalid, "S3 support is not enabled").into());
-
- #[cfg(s3)]
- s3::operator_for_path(path)?
- } else {
- let builder = opendal::services::Fs::default().root(path);
- opendal::Operator::new(builder)?.finish()
- };
-
- OPERATORS_BY_PATH.insert(path.to_string(), operator.clone());
-
- Ok(operator)
-}
-
-#[cfg(s3)]
-mod s3 {
- use reqwest::Url;
-
- use crate::error::Error;
-
- pub(super) fn is_uri(path: &str) -> bool {
- path.starts_with("s3://")
- }
-
- pub(super) fn join_path(base: &str, child: &str) -> String {
- if let Ok(mut url) = Url::parse(base) {
- let mut segments = path_segments(&url);
- segments.extend(child.split('/').filter(|segment| !segment.is_empty()).map(ToString::to_string));
- set_path_segments(&mut url, &segments);
- return url.to_string();
- }
-
- let base = base.trim_end_matches('/');
- let child = child.trim_start_matches('/');
- if base.is_empty() {
- child.to_string()
- } else if child.is_empty() {
- base.to_string()
- } else {
- format!("{base}/{child}")
- }
- }
-
- pub(super) fn with_extension(path: &str, extension: &str) -> String {
- if let Ok(mut url) = Url::parse(path) {
- let mut segments = path_segments(&url);
- if let Some(file_name) = segments.last_mut() {
- file_name.push('.');
- file_name.push_str(extension);
- set_path_segments(&mut url, &segments);
- return url.to_string();
- }
- }
-
- format!("{path}.{extension}")
- }
-
- pub(super) fn parent(path: &str) -> Option {
- if let Ok(mut url) = Url::parse(path) {
- let mut segments = path_segments(&url);
- segments.pop()?;
- set_path_segments(&mut url, &segments);
- return Some(url.to_string());
- }
-
- std::path::Path::new(path).parent()?.to_str().map(ToString::to_string)
- }
-
- pub(super) fn file_name(path: &str) -> Option {
- if let Ok(url) = Url::parse(path) {
- return path_segments(&url).pop();
- }
-
- std::path::Path::new(path).file_name()?.to_str().map(ToString::to_string)
- }
-
- fn path_segments(url: &Url) -> Vec {
- url.path_segments()
- .map(|segments| segments.filter(|segment| !segment.is_empty()).map(ToString::to_string).collect())
- .unwrap_or_default()
- }
-
- fn set_path_segments(url: &mut Url, segments: &[String]) {
- if segments.is_empty() {
- url.set_path("");
- } else {
- url.set_path(&format!("/{}", segments.join("/")));
- }
- }
-
- pub(super) fn operator_for_path(path: &str) -> Result {
- use crate::http_client::aws::AwsReqwestConnector;
- use aws_config::{default_provider::credentials::DefaultCredentialsChain, provider_config::ProviderConfig};
- use opendal::Configurator;
- use reqsign_aws_v4::Credential;
- use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain};
-
- // This is a custom AWS credential loader that uses the official AWS Rust
- // SDK config crate to load credentials. This ensures maximum compatibility
- // with AWS credential configurations. For example, OpenDAL doesn't support
- // AWS SSO temporary credentials yet.
- #[derive(Debug)]
- struct OpenDALS3CredentialProvider;
-
- impl ProvideCredential for OpenDALS3CredentialProvider {
- type Credential = Credential;
-
- async fn provide_credential(&self, _ctx: &Context) -> reqsign_core::Result |