| Crates.io | crypsol_storage |
| lib.rs | crypsol_storage |
| version | 0.1.0 |
| created_at | 2025-12-20 10:37:54.463688+00 |
| updated_at | 2025-12-20 10:37:54.463688+00 |
| description | AWS S3 storage library for Rust services with image processing, validation, and thumbnail generation. |
| homepage | |
| repository | https://github.com/crypsol/crypsol_storage |
| max_upload_size | |
| id | 1996325 |
| size | 114,625 |
A production-ready AWS S3 storage library for Rust services with image processing, validation, and thumbnail generation.
Add to your Cargo.toml:
[dependencies]
crypsol_storage = "0.1"
With Serde support:
[dependencies]
crypsol_storage = { version = "0.1", features = ["serde"] }
| Variable | Required | Default | Description |
|---|---|---|---|
S3_AWS_ACCESS_KEY |
Yes | - | AWS Access Key ID |
S3_AWS_SECRET_KEY |
Yes | - | AWS Secret Access Key |
S3_AWS_REGION |
No | us-east-1 |
AWS Region |
S3_BUCKET_NAME |
No | crypsol-storage |
S3 Bucket Name |
S3_PUBLIC_BASE_URL |
No | Auto-generated | CDN or custom domain URL |
S3_MAX_FILE_SIZE_MB |
No | 5 |
Maximum file size in MB |
use crypsol_storage::{upload_image_with_config, ImageUploadConfig, Error};
#[tokio::main]
async fn main() -> Result<(), Error> {
// Read image bytes
let image_data = std::fs::read("photo.jpg")?;
// Upload with default config (200x200 main, 50x50 thumbnail)
let config = ImageUploadConfig::default();
let result = upload_image_with_config(&image_data, "image/jpeg", &config).await?;
println!("Image URL: {}", result.url);
println!("Thumbnail URL: {}", result.thumbnail_url);
Ok(())
}
use crypsol_storage::{upload_image_with_config, ImageUploadConfig};
let config = ImageUploadConfig {
width: 800,
height: 600,
thumbnail_width: 150,
thumbnail_height: 150,
folder: "products".to_string(),
maintain_aspect_ratio: true,
};
let result = upload_image_with_config(&image_data, "image/png", &config).await?;
use crypsol_storage::upload_image_with_key;
// Full control over the S3 path
let result = upload_image_with_key(
&image_data,
"image/jpeg",
"users/123/profile.jpg", // Custom key
200, // width
200, // height
50, // thumbnail_width
50, // thumbnail_height
).await?;
use crypsol_storage::upload_file;
let pdf_data = std::fs::read("document.pdf")?;
let result = upload_file(&pdf_data, "application/pdf", "documents", "pdf").await?;
println!("File URL: {}", result.url);
use crypsol_storage::delete_image_with_thumbnail;
// Deletes both main image and thumbnail
delete_image_with_thumbnail("profiles/2025/01/21/abc123.jpg").await?;
use crypsol_storage::file_exists;
if file_exists("profiles/2025/01/21/abc123.jpg").await? {
println!("File exists!");
}
use crypsol_storage::generate_presigned_url;
// Generate URL valid for 1 hour (3600 seconds)
let url = generate_presigned_url("private/document.pdf", 3600).await?;
println!("Temporary URL: {}", url);
use crypsol_storage::extract_key_from_url;
let url = "https://bucket.s3.us-east-1.amazonaws.com/profiles/image.jpg";
if let Some(key) = extract_key_from_url(url) {
println!("Key: {}", key); // "profiles/image.jpg"
}
use crypsol_storage::{validate_content_type, ALLOWED_IMAGE_TYPES};
// Check if content type is allowed
validate_content_type("image/jpeg")?; // Ok
validate_content_type("application/pdf")?; // Error
// Allowed types: image/jpeg, image/png, image/gif, image/webp
println!("Allowed types: {:?}", ALLOWED_IMAGE_TYPES);
use crypsol_storage::{validate_file_size, get_max_file_size};
let file_size = 2 * 1024 * 1024; // 2MB
validate_file_size(file_size)?; // Ok if under limit
println!("Max size: {} bytes", get_max_file_size());
use crypsol_storage::Error;
match upload_image_with_config(&data, content_type, &config).await {
Ok(result) => println!("Uploaded: {}", result.url),
Err(Error::InvalidFileType(got, allowed)) => {
println!("Invalid type: {}. Allowed: {}", got, allowed);
}
Err(Error::FileTooLarge(size, max)) => {
println!("File too large: {} bytes (max: {})", size, max);
}
Err(Error::ImageProcessing(msg)) => {
println!("Image processing failed: {}", msg);
}
Err(Error::AwsS3(msg)) => {
println!("S3 error: {}", msg);
}
Err(e) => println!("Error: {}", e),
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:HeadObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": ["https://your-domain.com"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]
MIT License - see LICENSE for details.
Zuhair Thabit - admin@crypsol.tech