use std::path::{Path, PathBuf};
use ff_format::VideoFrame;
use crate::error::DecodeError;
use crate::image::builder::ImageDecoder;
pub struct AsyncImageDecoder {
inner: ImageDecoder,
}
impl AsyncImageDecoder {
pub async fn open(path: impl AsRef<Path> + Send + 'static) -> Result<Self, DecodeError> {
let path: PathBuf = path.as_ref().to_path_buf();
let decoder = tokio::task::spawn_blocking(move || ImageDecoder::open(&path).build())
.await
.map_err(|e| DecodeError::Ffmpeg {
code: 0,
message: format!("spawn_blocking panicked: {e}"),
})??;
Ok(Self { inner: decoder })
}
pub async fn decode(self) -> Result<VideoFrame, DecodeError> {
tokio::task::spawn_blocking(move || self.inner.decode())
.await
.map_err(|e| DecodeError::Ffmpeg {
code: 0,
message: format!("spawn_blocking panicked: {e}"),
})?
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn async_image_decoder_should_fail_on_missing_file() {
let result = AsyncImageDecoder::open("/nonexistent/path/photo.png").await;
assert!(
matches!(result, Err(DecodeError::FileNotFound { .. })),
"expected FileNotFound"
);
}
}