use crate::error::Result;
use reqwest::Response;
use std::path::Path;
#[derive(Debug)]
pub struct TinifyResult {
response: Option<Response>,
}
impl TinifyResult {
pub fn new(response: Response) -> Self {
Self {
response: Some(response),
}
}
pub async fn to_buffer(&mut self) -> Result<Vec<u8>> {
let response = self.response.take().expect("Response has been consumed");
let bytes = response.bytes().await?;
Ok(bytes.to_vec())
}
pub async fn to_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
let bytes = self.to_buffer().await?;
tokio::fs::write(path, bytes).await?;
Ok(())
}
pub fn compression_count(&self) -> Option<u32> {
self.response
.as_ref()?
.headers()
.get("Compression-Count")
.and_then(|v| v.to_str().ok())
.and_then(|s| s.parse().ok())
}
pub fn image_width(&self) -> Option<u32> {
self.response
.as_ref()?
.headers()
.get("Image-Width")
.and_then(|v| v.to_str().ok())
.and_then(|s| s.parse().ok())
}
pub fn image_height(&self) -> Option<u32> {
self.response
.as_ref()?
.headers()
.get("Image-Height")
.and_then(|v| v.to_str().ok())
.and_then(|s| s.parse().ok())
}
pub fn content_type(&self) -> Option<String> {
self.response
.as_ref()?
.headers()
.get("Content-Type")
.and_then(|v| v.to_str().ok())
.map(String::from)
}
pub fn content_length(&self) -> Option<u64> {
self.response
.as_ref()?
.headers()
.get("Content-Length")
.and_then(|v| v.to_str().ok())
.and_then(|s| s.parse().ok())
}
}
impl From<TinifyResult> for Vec<u8> {
fn from(mut result: TinifyResult) -> Self {
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current()
.block_on(async { result.to_buffer().await.unwrap_or_default() })
})
}
}