use crate::client::Client;
use crate::error::Result;
use crate::options::{ConvertOptions, PreserveOptions, ResizeOptions, StoreOptions};
use crate::result::TinifyResult;
use std::sync::Arc;
use tracing::{info, instrument};
#[derive(Debug, Clone)]
pub struct Source {
location: String,
client: Arc<Client>,
}
impl Source {
pub fn new(location: String, client: Arc<Client>) -> Self {
Self { location, client }
}
#[instrument(skip(self), fields(location = %self.location))]
pub async fn resize(&self, options: ResizeOptions) -> Result<TinifyResult> {
info!("Resizing image at location: {}", self.location);
crate::Tinify::validate_dimensions(options.width, options.height)?;
let body = serde_json::to_vec(&serde_json::json!({ "resize": options }))?;
let response = self.client.post(&self.location, Some(body)).await?;
Ok(TinifyResult::new(response))
}
#[instrument(skip(self), fields(location = %self.location))]
pub async fn convert(&self, options: ConvertOptions) -> Result<TinifyResult> {
info!("Converting image format at location: {}", self.location);
let body = serde_json::to_vec(&serde_json::json!({ "convert": options }))?;
let response = self.client.post(&self.location, Some(body)).await?;
Ok(TinifyResult::new(response))
}
#[instrument(skip(self), fields(location = %self.location))]
pub async fn preserve(&self, options: PreserveOptions) -> Result<TinifyResult> {
info!(
"Preserving metadata for image at location: {}",
self.location
);
let body = serde_json::to_vec(&options)?;
let response = self.client.post(&self.location, Some(body)).await?;
Ok(TinifyResult::new(response))
}
#[instrument(skip(self), fields(location = %self.location))]
pub async fn store(&self, options: StoreOptions) -> Result<TinifyResult> {
info!(
"Storing image to cloud storage from location: {}",
self.location
);
let store_request = crate::options::StoreRequest { store: options };
let body = serde_json::to_vec(&store_request)?;
let response = self.client.post(&self.location, Some(body)).await?;
Ok(TinifyResult::new(response))
}
#[instrument(skip(self), fields(location = %self.location))]
pub async fn to_buffer(&self) -> Result<Vec<u8>> {
info!("Downloading image data from location: {}", self.location);
let response = self.client.get(&self.location).await?;
let mut result = TinifyResult::new(response);
result.to_buffer().await
}
#[instrument(skip(self), fields(location = %self.location, path = %path.as_ref().display()))]
pub async fn to_file<P: AsRef<std::path::Path>>(&self, path: P) -> Result<()> {
let path_display = path.as_ref().display().to_string();
info!(
"Saving image from location {} to file: {}",
self.location, path_display
);
let response = self.client.get(&self.location).await?;
let mut result = TinifyResult::new(response);
result.to_file(path).await
}
pub fn location(&self) -> &str {
&self.location
}
}