use crate::primaries::Primary;
use waddling_errors::ComponentIdDocumented;
use waddling_errors::prelude::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Storage;
impl ComponentId for Storage {
fn as_str(&self) -> &'static str {
"Storage"
}
}
impl ComponentIdDocumented for Storage {
fn description(&self) -> Option<&'static str> {
Some(
"S3-compatible object storage. Handles file uploads, downloads, versioning, \
and presigned URL generation.",
)
}
fn examples(&self) -> &'static [&'static str] {
&[
"E.Storage.Permission.008: S3 bucket access denied",
"C.Storage.Data.025: Object integrity check failed (corrupt upload)",
"K.Storage.Data.999: Multipart upload completed successfully",
]
}
fn tags(&self) -> &'static [&'static str] {
&["files", "s3", "objects"]
}
}
pub const ERR_PERMISSION_DENIED: Code<Storage, Primary> =
Code::error(Storage, Primary::Permission, 8);
pub const CRIT_DATA_CORRUPTED: Code<Storage, Primary> = Code::critical(Storage, Primary::Data, 25);
pub const ERR_DATA_ALREADYEXISTS: Code<Storage, Primary> = Code::error(Storage, Primary::Data, 22);
pub const ERR_DATA_NOTFOUND: Code<Storage, Primary> = Code::error(Storage, Primary::Data, 21);
pub const COMPLETE_UPLOAD: Code<Storage, Primary> = Code::completed(Storage, Primary::Data, 999);
pub const TRACE_OPERATION: Code<Storage, Primary> = Code::trace(Storage, Primary::Data, 100);
#[cfg(feature = "doc-gen")]
pub fn register_component(generator: &mut waddling_errors::doc_generator::DocRegistry) {
use waddling_errors::Role;
generator.register_component(
"Storage",
Some("S3-compatible object storage. Handles file uploads, downloads, versioning, and presigned URL generation. Implements multipart uploads for large files, automatic retry, and integrity verification using checksums."),
&[
"Multipart upload for large files",
"Presigned URL generation (GET/PUT)",
"Object versioning and lifecycle",
"Server-side encryption (SSE)",
"Checksum verification (MD5/SHA256)",
"Cross-region replication",
],
&["Storage", "s3", "objects", "files", "upload", "cloud"]);
generator.register_component_location_with_role(
"Storage",
"examples/complete_system/components/storage.rs",
Some(Role::Public),
);
generator.register_component_location_with_role(
"Storage",
"examples/storage_usage.rs",
Some(Role::Public),
);
generator.register_component_location_with_role(
"Storage",
"src/storage/upload_monitor.rs",
Some(Role::Developer),
);
generator.register_component_location_with_role(
"Storage",
"src/storage/debug_utils.rs",
Some(Role::Developer),
);
generator.register_component_location_with_role(
"Storage",
"src/storage/s3_client.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Storage",
"src/storage/upload_manager.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Storage",
"src/handlers/file_upload_handler.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Storage",
"src/storage/encryption_keys.rs",
Some(Role::Internal),
);
}
#[cfg(feature = "doc-gen")]
pub fn register_errors(generator: &mut waddling_errors::doc_generator::DocRegistry) {
use waddling_errors::Role;
let errors = vec![
(
"E.Storage.Permission.008",
"S3 bucket access denied",
&[
"Check IAM permissions",
"Verify bucket policy",
"Update credentials",
][..],
&["Storage", "s3", "permissions"][..],
Role::Internal,
),
(
"C.Storage.Data.025",
"CRITICAL: Object corruption detected",
&["Retry upload", "Verify checksums", "Check network"],
&["Storage", "integrity", "critical"],
Role::Internal,
),
(
"E.Storage.Data.022",
"Object already exists - upload conflict",
&[
"Use unique filename",
"Enable versioning",
"Check existing object",
],
&["Storage", "conflict"],
Role::Developer,
),
(
"E.Storage.Data.021",
"Object not found in storage",
&[
"Verify object key",
"Check bucket name",
"Review deletion logs",
],
&["Storage", "not-found"],
Role::Public,
),
(
"K.Storage.Data.999",
"Multipart upload completed successfully",
&["Upload finished", "Object available"],
&["Storage", "success"],
Role::Public,
),
(
"T.Storage.Data.100",
"Storage operation trace - debugging enabled",
&["Debug trace active", "Check logs for details"],
&["Storage", "debugging"],
Role::Internal,
),
];
for (code, desc, hints, tags, role) in &errors {
let _ = generator.register(*code, *desc, hints, tags);
let snippet = match role {
Role::Internal => format!(
"// Internal debugging\nlog::error!(\"[{}] {}\");",
code, desc
),
Role::Developer => format!(
"// Developer API usage\nif let Err(e) = operation() {{\n eprintln!(\"Error: {}\");\n}}",
code
),
Role::Public => format!(
"// Public error handling\nmatch result {{\n Err(_) => println!(\"Operation failed: {}\"),\n Ok(_) => println!(\"Success\"),\n}}",
desc
),
};
generator.add_snippet_for_role(
format!("{:?} - Usage Example", role),
"rust",
snippet,
*role,
);
}
}
pub fn demo() {
println!("☁️ STORAGE Component Errors:\n");
println!(" {} - Permission denied", ERR_PERMISSION_DENIED.code());
println!(" {} - Data corrupted", CRIT_DATA_CORRUPTED.code());
println!(" {} - Already exists", ERR_DATA_ALREADYEXISTS.code());
println!(" {} - Not found", ERR_DATA_NOTFOUND.code());
println!(" {} - Upload complete", COMPLETE_UPLOAD.code());
println!(" {} - Trace operation", TRACE_OPERATION.code());
}