use super::codecs::CvEncoder; use super::error::ErrorReason; use crate::conversions::NdAsImage; use crate::NdCvError; use error_stack::*; use ndarray::ArrayBase; use std::path::Path; pub trait Encodable { fn encode(&self, encoder: &E) -> Result, NdCvError> { let input = self.transform()?; encoder.encode(input) } fn write(&self, path: impl AsRef, encoder: &E) -> Result<(), NdCvError> { let buf = self.encode(encoder)?; std::fs::write(path, buf) .map_err(|e| match e.kind() { std::io::ErrorKind::NotFound => { Report::new(e).attach_printable(ErrorReason::ImageWriteFileNotFound) } std::io::ErrorKind::PermissionDenied => { Report::new(e).attach_printable(ErrorReason::ImageWritePermissionDenied) } std::io::ErrorKind::OutOfMemory => { Report::new(e).attach_printable(ErrorReason::OutOfMemory) } std::io::ErrorKind::StorageFull => { Report::new(e).attach_printable(ErrorReason::OutOfStorage) } _ => Report::new(e).attach_printable(ErrorReason::ImageWriteOtherError), }) .change_context(NdCvError) } fn transform(&self) -> Result<::Input<'_>, NdCvError>; } pub trait Encoder { type Input<'a> where Self: 'a; fn encode(&self, input: Self::Input<'_>) -> Result, NdCvError>; } impl, D: ndarray::Dimension> Encodable for ArrayBase where Self: NdAsImage, { fn transform(&self) -> Result<::Input<'_>, NdCvError> { self.as_image_mat() } }