Compare commits

...

1 Commits

Author SHA1 Message Date
overtrue ea40a41c9b chore(protocols): drop 43 no-op dead_code allows from swift
backlog#1823 step 8, partial. The swift module carries 43 #[allow(dead_code)] attributes, most with a comment naming a consumer: "Used by handler", "Handler integration: GET container", "Used by handler and object.rs".

Every one of them suppresses nothing. crates/protocols/src/lib.rs declares `pub mod swift`, and swift/mod.rs declares all 22 submodules `pub mod`, so every item is publicly reachable and dead_code never applied to it. Removing all 43 leaves the warning count at zero, in both the default and --features swift lanes.

That is also why those comments survived. They assert who calls the item — a claim the compiler normally settles on its own — and the compiler had been silenced by the visibility chain.

The rest of step 8 needs a decision this PR does not make. Downgrading the 22 submodules to `pub(crate) mod` does restore detection, and it surfaces 39 real items, 16 of them the whole of sync.rs: SyncConfig, SyncStatus, SyncQueueEntry, ConflictResolution and every function and constant around them, i.e. Swift container sync is built and never wired.

But the `pub mod` chain is load-bearing. Six integration tests under crates/protocols/tests are separate crates that import the submodules directly (swift::quota, swift::slo, swift::symlink, swift::sync, swift::tempurl, swift::container), and the downgrade fails to compile them. Restoring dead-code detection for this module therefore depends on first deciding whether those tests move in-crate — which is a testing-strategy call, not a cleanup one.

Verification: cargo check -p rustfs-protocols warning-free in the default lane and with --features swift (lib and --tests); clippy --features swift --lib --tests -D warnings clean; cargo nextest run -p rustfs-protocols --features swift 441 passed; make pre-commit exit 0.

Ref rustfs/backlog#1823 (step 8).
2026-08-17 00:51:30 +08:00
6 changed files with 0 additions and 43 deletions
-2
View File
@@ -38,7 +38,6 @@ use std::collections::HashMap;
/// - Account format is invalid
/// - Credentials don't contain project_id
/// - Account project_id doesn't match credentials project_id
#[allow(dead_code)] // Used by Swift implementation
pub fn validate_account_access(account: &str, credentials: &Credentials) -> SwiftResult<String> {
// Extract project_id from account (strip "AUTH_" prefix)
let account_project_id = account
@@ -70,7 +69,6 @@ pub fn validate_account_access(account: &str, credentials: &Credentials) -> Swif
///
/// Admin users (with "admin" or "reseller_admin" roles) can perform
/// cross-tenant operations and administrative tasks.
#[allow(dead_code)] // Used by Swift implementation
pub fn is_admin_user(credentials: &Credentials) -> bool {
credentials
.claims
-14
View File
@@ -144,7 +144,6 @@ impl ContainerMapper {
/// - S3 bucket name compatible (only uses [a-z0-9-])
/// - Deterministic mapping (same input always produces same bucket name)
/// - Fixed-length prefix (16 hex chars = 8 bytes)
#[allow(dead_code)] // Used in: create/delete container operations
pub fn swift_to_s3_bucket(&self, container: &str, project_id: &str) -> String {
if self.config.tenant_prefix_enabled {
let hash = self.hash_project_id(project_id);
@@ -216,7 +215,6 @@ pub fn bucket_info_to_container(info: &BucketInfo, mapper: &ContainerMapper, pro
/// 2. Lists all S3 buckets
/// 3. Filters to buckets belonging to this tenant (using tenant prefix)
/// 4. Converts BucketInfo to Swift Container format
#[allow(dead_code)] // Used by handler: list containers
pub async fn list_containers(account: &str, credentials: &Credentials) -> SwiftResult<Vec<Container>> {
// Validate account access and extract project_id
let project_id = validate_account_access(account, credentials)?;
@@ -279,7 +277,6 @@ pub async fn list_containers(account: &str, credentials: &Credentials) -> SwiftR
/// - Returns 201 Created on success
/// - Returns 202 Accepted if container already exists
/// - Returns 400 Bad Request for invalid container names
#[allow(dead_code)] // Used by handler
pub async fn create_container(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<bool> {
// Validate account access and extract project_id
let project_id = validate_account_access(account, credentials)?;
@@ -348,7 +345,6 @@ fn validate_container_name(container: &str) -> SwiftResult<()> {
}
/// Container metadata for HEAD response
#[allow(dead_code)] // TODO: Remove once Swift API integration is complete
#[derive(Debug, Clone)]
pub struct ContainerMetadata {
/// Number of objects in container
@@ -411,7 +407,6 @@ pub(crate) async fn get_container_custom_metadata(
/// - HEAD /v1/{account}/{container} returns container metadata
/// - Returns 204 No Content on success with headers
/// - Returns 404 Not Found if container doesn't exist
#[allow(dead_code)] // Used by handler
pub async fn get_container_metadata(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<ContainerMetadata> {
let (bucket_name, bucket_info, custom_metadata) = get_container_metadata_base(account, container, credentials).await?;
@@ -448,7 +443,6 @@ pub async fn get_container_metadata(account: &str, container: &str, credentials:
/// - The update is additive: items the request does not name keep their stored
/// value, and removal is explicit, via `X-Remove-Container-Meta-{name}` or an
/// empty value
#[allow(dead_code)] // Used by handler
pub async fn update_container_metadata(
account: &str,
container: &str,
@@ -520,7 +514,6 @@ pub async fn update_container_metadata(
/// - Returns 204 No Content on success
/// - Returns 404 Not Found if container doesn't exist
/// - Returns 409 Conflict if container is not empty
#[allow(dead_code)] // Used by handler
pub async fn delete_container(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<()> {
// Validate account access and extract project_id
let project_id = validate_account_access(account, credentials)?;
@@ -603,7 +596,6 @@ pub async fn delete_container(account: &str, container: &str, credentials: &Cred
/// - Account validation fails
/// - Container doesn't exist
/// - Storage layer errors occur
#[allow(dead_code)] // Handler integration: GET container
pub async fn list_objects(
account: &str,
container: &str,
@@ -706,7 +698,6 @@ pub async fn list_objects(
/// Versioning configuration is stored as an S3 bucket tag:
/// - Tag key: `swift-versions-location`
/// - Tag value: archive container name
#[allow(dead_code)] // Used by handler
pub async fn enable_versioning(
account: &str,
container: &str,
@@ -795,7 +786,6 @@ pub async fn enable_versioning(
/// * `account` - Account identifier
/// * `container` - Container name to disable versioning on
/// * `credentials` - Keystone credentials
#[allow(dead_code)] // Used by handler
pub async fn disable_versioning(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<()> {
// Validate account access
let project_id = validate_account_access(account, credentials)?;
@@ -855,7 +845,6 @@ pub async fn disable_versioning(account: &str, container: &str, credentials: &Cr
/// # Returns
/// - Some(archive_container_name) if versioning is enabled
/// - None if versioning is not enabled
#[allow(dead_code)] // Used by handler and object.rs
pub async fn get_versions_location(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<Option<String>> {
// Validate account access
let project_id = validate_account_access(account, credentials)?;
@@ -918,7 +907,6 @@ pub async fn get_versions_location(account: &str, container: &str, credentials:
/// &credentials
/// ).await?;
/// ```
#[allow(dead_code)] // Used by handler
pub async fn set_container_acl(
account: &str,
container: &str,
@@ -1022,7 +1010,6 @@ pub async fn set_container_acl(
/// println!("Container is publicly readable");
/// }
/// ```
#[allow(dead_code)] // Used by handler
pub async fn get_container_acl(
account: &str,
container: &str,
@@ -1083,7 +1070,6 @@ pub async fn get_container_acl(
///
/// # Returns
/// Ok(()) if ACLs were deleted successfully
#[allow(dead_code)] // Used by handler
pub async fn delete_container_acl(account: &str, container: &str, credentials: &Credentials) -> SwiftResult<()> {
// Setting both ACLs to None removes them
set_container_acl(account, container, None, None, credentials).await
-1
View File
@@ -20,7 +20,6 @@ use std::fmt;
/// Swift-specific error type
#[derive(Debug)]
#[allow(dead_code)] // Error variants used by Swift implementation
pub enum SwiftError {
/// 400 Bad Request
BadRequest(String),
-21
View File
@@ -122,12 +122,10 @@ fn swift_user_metadata(headers: &HeaderMap) -> Option<HashMap<String, String>> {
///
/// Handles URL encoding/decoding and path normalization for Swift object keys.
/// Swift object names can contain any UTF-8 characters except null bytes.
#[allow(dead_code)] // Used in: object operations
pub struct ObjectKeyMapper;
impl ObjectKeyMapper {
/// Create a new object key mapper
#[allow(dead_code)] // Used in: object operations
pub fn new() -> Self {
Self
}
@@ -140,7 +138,6 @@ impl ObjectKeyMapper {
/// - Not contain null bytes
/// - Not contain '..' path segments (directory traversal)
/// - Not start with '/' (leading slash handled by routing)
#[allow(dead_code)] // Used in: object operations
pub fn validate_object_name(object: &str) -> SwiftResult<()> {
if object.is_empty() {
return Err(SwiftError::BadRequest("Object name cannot be empty".to_string()));
@@ -183,7 +180,6 @@ impl ObjectKeyMapper {
/// Example:
/// - Swift: "photos/vacation/beach photo.jpg"
/// - S3: "photos/vacation/beach photo.jpg"
#[allow(dead_code)] // Used in: object operations
pub fn swift_to_s3_key(object: &str) -> SwiftResult<String> {
Self::validate_object_name(object)?;
Ok(object.to_string())
@@ -193,7 +189,6 @@ impl ObjectKeyMapper {
///
/// This is essentially an identity transformation since we store
/// Swift object names as-is in S3.
#[allow(dead_code)] // Used in: object operations
pub fn s3_to_swift_name(key: &str) -> String {
key.to_string()
}
@@ -208,7 +203,6 @@ impl ObjectKeyMapper {
/// - Object: "vacation/beach.jpg"
/// - Bucket: "abc123:photos"
/// - Key: "vacation/beach.jpg"
#[allow(dead_code)] // Used in: object operations
pub fn build_s3_key(object: &str) -> SwiftResult<String> {
Self::swift_to_s3_key(object)
}
@@ -220,7 +214,6 @@ impl ObjectKeyMapper {
///
/// Example URL: /v1/AUTH_abc/container/path%2Fto%2Ffile.txt
/// Decoded: "path/to/file.txt"
#[allow(dead_code)] // Used in: object operations
pub fn decode_object_from_url(encoded: &str) -> SwiftResult<String> {
// Decode percent-encoding
let decoded = urlencoding::decode(encoded).map_err(|e| SwiftError::BadRequest(format!("Invalid URL encoding: {}", e)))?;
@@ -233,7 +226,6 @@ impl ObjectKeyMapper {
///
/// When constructing URLs (e.g., for redirect responses), we need to
/// percent-encode object names.
#[allow(dead_code)] // Used in: object operations
pub fn encode_object_for_url(object: &str) -> String {
urlencoding::encode(object).to_string()
}
@@ -241,7 +233,6 @@ impl ObjectKeyMapper {
/// Check if object name represents a directory (pseudo-directory)
///
/// In Swift, objects ending with '/' are treated as directory markers.
#[allow(dead_code)] // Used in: object operations
pub fn is_directory_marker(object: &str) -> bool {
object.ends_with('/')
}
@@ -250,7 +241,6 @@ impl ObjectKeyMapper {
///
/// Removes redundant slashes and normalizes the path while preserving
/// trailing slashes for directory markers.
#[allow(dead_code)] // Used in: object operations
pub fn normalize_path(object: &str) -> String {
// Split by '/', filter out empty segments (except if it's the end)
let has_trailing_slash = object.ends_with('/');
@@ -324,7 +314,6 @@ fn sanitize_storage_error<E: std::fmt::Display>(operation: &str, error: E) -> Sw
/// # Returns
/// * `Ok(etag)` - Object ETag on success
/// * `Err(SwiftError)` - Error if validation fails or upload fails
#[allow(dead_code)] // Handler integration: PUT object
pub async fn put_object<R>(
account: &str,
container: &str,
@@ -445,7 +434,6 @@ where
///
/// Similar to put_object, but allows directly specifying metadata instead of extracting from headers.
/// This is used internally for storing SLO manifests and marker objects.
#[allow(dead_code)] // Used by SLO implementation
pub async fn put_object_with_metadata<R>(
account: &str,
container: &str,
@@ -549,7 +537,6 @@ where
/// - `bytes=1000-1999` - Bytes 1000-1999
/// - `bytes=1000-` - From byte 1000 to end
/// - `bytes=-500` - Last 500 bytes
#[allow(dead_code)] // Handler integration: GET object
pub async fn get_object(
account: &str,
container: &str,
@@ -608,7 +595,6 @@ pub async fn get_object(
/// # Returns
/// * `Ok(object_info)` - Object metadata (ObjectInfo)
/// * `Err(SwiftError)` - Error if validation fails or object not found
#[allow(dead_code)] // Handler integration: HEAD object
pub async fn head_object(
account: &str,
container: &str,
@@ -671,7 +657,6 @@ pub async fn head_object(
/// # Returns
/// * `Ok(())` - Object deleted successfully (or didn't exist)
/// * `Err(SwiftError)` - Error if validation fails or deletion fails
#[allow(dead_code)] // Handler integration: DELETE object
pub async fn delete_object(account: &str, container: &str, object: &str, credentials: &Credentials) -> SwiftResult<()> {
// 1. Validate account access and get project_id
let project_id = validate_account_access(account, credentials)?;
@@ -732,7 +717,6 @@ pub async fn delete_object(account: &str, container: &str, object: &str, credent
/// # Returns
/// * `Ok(())` - Metadata updated successfully
/// * `Err(SwiftError)` - Error if validation fails, object not found, or update fails
#[allow(dead_code)] // Handler integration: POST object
pub async fn update_object_metadata(
account: &str,
container: &str,
@@ -846,7 +830,6 @@ pub async fn update_object_metadata(
/// # Handler Integration Note
/// The current handler architecture needs to be updated to pass headers through
/// to support COPY method and X-Copy-From header detection. See handler.rs for details.
#[allow(dead_code)] // Handler integration: COPY object
#[allow(clippy::too_many_arguments)] // Necessary for full copy functionality
pub async fn copy_object(
src_account: &str,
@@ -979,7 +962,6 @@ pub async fn copy_object(
/// assert_eq!(container, "my-container");
/// assert_eq!(object, "path/to/file.txt");
/// ```
#[allow(dead_code)] // Handler integration: COPY method
pub fn parse_destination_header(destination: &str) -> SwiftResult<(String, String)> {
let destination = destination.trim_start_matches('/');
let parts: Vec<&str> = destination.splitn(2, '/').collect();
@@ -1013,7 +995,6 @@ pub fn parse_destination_header(destination: &str) -> SwiftResult<(String, Strin
/// # Returns
/// * `Ok((container, object))` - Parsed container and object names
/// * `Err(SwiftError)` - Error if format is invalid
#[allow(dead_code)] // Handler integration: X-Copy-From
pub fn parse_copy_from_header(copy_from: &str) -> SwiftResult<(String, String)> {
// Same parsing logic as Destination header
parse_destination_header(copy_from)
@@ -1042,7 +1023,6 @@ pub fn parse_copy_from_header(copy_from: &str) -> SwiftResult<(String, String)>
/// assert_eq!(range.start, 0);
/// assert_eq!(range.end, 1023);
/// ```
#[allow(dead_code)] // Handler integration: Range header
pub fn parse_range_header(range_str: &str) -> SwiftResult<HTTPRangeSpec> {
if !range_str.starts_with("bytes=") {
return Err(SwiftError::BadRequest("Range header must start with 'bytes='".to_string()));
@@ -1124,7 +1104,6 @@ pub fn parse_range_header(range_str: &str) -> SwiftResult<HTTPRangeSpec> {
/// let header = format_content_range(0, 1023, 5000);
/// assert_eq!(header, "bytes 0-1023/5000");
/// ```
#[allow(dead_code)] // Handler integration: Range header
pub fn format_content_range(start: i64, end: i64, total: i64) -> String {
format!("bytes {}-{}/{}", start, end, total)
}
-2
View File
@@ -50,7 +50,6 @@ pub enum SwiftRoute {
impl SwiftRoute {
/// Get the account identifier from the route
#[allow(dead_code)] // Public API for future use
pub fn account(&self) -> &str {
match self {
SwiftRoute::Account { account, .. } => account,
@@ -60,7 +59,6 @@ impl SwiftRoute {
}
/// Extract project_id from account string (removes AUTH_ prefix)
#[allow(dead_code)] // Public API for future use
pub fn project_id(&self) -> Option<&str> {
let account = self.account();
ACCOUNT_PATTERN
-3
View File
@@ -19,7 +19,6 @@ use std::collections::HashMap;
/// Swift container metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(dead_code)] // Used in container listing operations
pub struct Container {
/// Container name
pub name: String,
@@ -34,7 +33,6 @@ pub struct Container {
/// Swift object metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(dead_code)] // Used in object listing operations
pub struct Object {
/// Object name (key)
pub name: String,
@@ -50,7 +48,6 @@ pub struct Object {
/// Swift metadata extracted from headers
#[derive(Debug, Clone, Default)]
#[allow(dead_code)] // Used by Swift implementation
pub struct SwiftMetadata {
/// Custom metadata key-value pairs (from X-Container-Meta-* or X-Object-Meta-*)
pub metadata: HashMap<String, String>,