diff --git a/examples/thumbnail.rs b/examples/thumbnail.rs index caea214..e4d7c8f 100644 --- a/examples/thumbnail.rs +++ b/examples/thumbnail.rs @@ -14,37 +14,58 @@ async fn main() -> Result<(), Box> { // Download thumbnail (small size, default) println!("Downloading thumbnail..."); - let thumbnail = client + let response = client .assets() .thumbnail(asset_id) .size(AssetMediaSize::Thumbnail) .execute() .await?; - fs::write("/path/to/output/thumbnail.jpg", &thumbnail)?; - println!("Saved thumbnail: {} bytes", thumbnail.len()); + println!("Content type: {}", response.content_type()); + println!("Extension: {:?}", response.extension()); + + let ext = response.extension().unwrap_or("jpg"); + let output_path = format!("/path/to/output/thumbnail.{}", ext); + fs::write(&output_path, response.data())?; + println!( + "Saved thumbnail: {} bytes to {}", + response.data().len(), + output_path + ); // Download preview (medium size) - let preview = client + let response = client .assets() .thumbnail(asset_id) .size(AssetMediaSize::Preview) .execute() .await?; - fs::write("/path/to/output/preview.jpg", &preview)?; - println!("Saved preview: {} bytes", preview.len()); + let ext = response.extension().unwrap_or("jpg"); + let output_path = format!("/path/to/output/preview.{}", ext); + fs::write(&output_path, response.data())?; + println!( + "Saved preview: {} bytes to {}", + response.data().len(), + output_path + ); // Download fullsize - let fullsize = client + let response = client .assets() .thumbnail(asset_id) .size(AssetMediaSize::Fullsize) .execute() .await?; - fs::write("/path/to/output/fullsize.jpg", &fullsize)?; - println!("Saved fullsize: {} bytes", fullsize.len()); + let ext = response.extension().unwrap_or("jpg"); + let output_path = format!("/path/to/output/fullsize.{}", ext); + fs::write(&output_path, response.data())?; + println!( + "Saved fullsize: {} bytes to {}", + response.data().len(), + output_path + ); Ok(()) } diff --git a/src/apis/assets.rs b/src/apis/assets.rs index bcfafc0..aa94fe5 100644 --- a/src/apis/assets.rs +++ b/src/apis/assets.rs @@ -8,6 +8,44 @@ use crate::{ models::{AssetId, AssetMediaSize, AssetResponse, AssetUploadResponse, DeleteAssetsRequest}, }; +/// Response from downloading a thumbnail containing image data and metadata +#[derive(Debug, Clone)] +pub struct ThumbnailResponse { + /// The image data as bytes + pub data: bytes::Bytes, + /// The MIME type of the image (e.g., "image/jpeg", "image/png", "image/webp") + pub content_type: String, +} + +impl ThumbnailResponse { + /// Get the file extension based on content type + pub fn extension(&self) -> Option<&str> { + match self.content_type.as_str() { + "image/jpeg" | "image/jpg" => Some("jpg"), + "image/png" => Some("png"), + "image/webp" => Some("webp"), + "image/gif" => Some("gif"), + "image/tiff" => Some("tiff"), + _ => None, + } + } + + /// Get the content type + pub fn content_type(&self) -> &str { + &self.content_type + } + + /// Get the data + pub fn data(&self) -> &bytes::Bytes { + &self.data + } + + /// Convert to owned bytes + pub fn into_data(self) -> bytes::Bytes { + self.data + } +} + /// API for managing assets (photos and videos) #[derive(Debug, Clone)] pub struct AssetsApi { @@ -338,7 +376,7 @@ impl ThumbnailBuilder { } /// Execute the request - pub async fn execute(self) -> Result { + pub async fn execute(self) -> Result { let path = format!("/assets/{}/thumbnail", self.id); let mut req = self.client.get(&path); @@ -357,7 +395,17 @@ impl ThumbnailBuilder { } let response = self.client.execute(req.build()?).await?; - let bytes = response.bytes().await?; - Ok(bytes) + + // Get content type from response headers + let content_type = response + .headers() + .get("content-type") + .and_then(|ct| ct.to_str().ok()) + .map(String::from) + .unwrap_or_else(|| "application/octet-stream".to_string()); + + let data = response.bytes().await?; + + Ok(ThumbnailResponse { data, content_type }) } }