use std::sync::Arc;
use crate::error::ImageDataError;
use crate::ImageInfo;
pub trait AsImageView {
fn as_image_view(&self) -> Result<ImageView, ImageDataError>;
}
pub fn image_info(image: &impl AsImageView) -> Result<ImageInfo, ImageDataError> {
Ok(image.as_image_view()?.info())
}
#[derive(Debug, Copy, Clone)]
pub struct ImageView<'a> {
info: ImageInfo,
data: &'a [u8],
}
impl<'a> ImageView<'a> {
pub fn new(info: ImageInfo, data: &'a [u8]) -> Self {
Self { info, data }
}
pub fn info(&self) -> ImageInfo {
self.info
}
pub fn data(&self) -> &[u8] {
self.data
}
}
impl<'a> AsImageView for ImageView<'a> {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
Ok(*self)
}
}
pub enum Image {
Box(BoxImage),
Arc(ArcImage),
BoxDyn(Box<dyn AsImageView + Send>),
ArcDyn(Arc<dyn AsImageView + Sync + Send>),
Invalid(ImageDataError),
}
impl Clone for Image {
fn clone(&self) -> Self {
match self {
Self::Box(x) => Self::Box(x.clone()),
Self::Arc(x) => Self::Arc(x.clone()),
Self::BoxDyn(x) => match x.as_image_view() {
Ok(view) => Self::Box(BoxImage::new(view.info, view.data.into())),
Err(error) => Self::Invalid(error),
},
Self::ArcDyn(x) => Self::ArcDyn(x.clone()),
Self::Invalid(x) => Self::Invalid(x.clone()),
}
}
}
impl<T: AsImageView> AsImageView for Box<T> {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
self.as_ref().as_image_view()
}
}
impl<T: AsImageView> AsImageView for Arc<T> {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
self.as_ref().as_image_view()
}
}
#[derive(Debug, Clone)]
pub struct BoxImage {
info: ImageInfo,
data: Box<[u8]>,
}
#[derive(Debug, Clone)]
pub struct ArcImage {
info: ImageInfo,
data: Arc<[u8]>,
}
impl Image {
pub fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
match self {
Self::Box(x) => Ok(x.as_view()),
Self::Arc(x) => Ok(x.as_view()),
Self::BoxDyn(x) => x.as_image_view(),
Self::ArcDyn(x) => x.as_image_view(),
Self::Invalid(e) => Err(e.clone()),
}
}
}
impl AsImageView for Image {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
self.as_image_view()
}
}
impl BoxImage {
pub fn new(info: ImageInfo, data: Box<[u8]>) -> Self {
Self { info, data }
}
pub fn as_view(&self) -> ImageView {
ImageView::new(self.info, &self.data)
}
pub fn info(&self) -> ImageInfo {
self.info
}
pub fn data(&self) -> &[u8] {
&self.data
}
}
impl AsImageView for BoxImage {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
Ok(self.as_view())
}
}
impl ArcImage {
pub fn new(info: ImageInfo, data: Arc<[u8]>) -> Self {
Self { info, data }
}
pub fn as_view(&self) -> ImageView {
ImageView::new(self.info, &self.data)
}
pub fn info(&self) -> ImageInfo {
self.info
}
pub fn data(&self) -> &[u8] {
&self.data
}
}
impl AsImageView for ArcImage {
fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
Ok(self.as_view())
}
}
impl From<ImageView<'_>> for BoxImage {
fn from(other: ImageView) -> Self {
Self {
info: other.info,
data: other.data.into(),
}
}
}
impl From<&'_ ImageView<'_>> for BoxImage {
fn from(other: &ImageView) -> Self {
Self {
info: other.info,
data: other.data.into(),
}
}
}
impl From<ImageView<'_>> for ArcImage {
fn from(other: ImageView) -> Self {
Self {
info: other.info,
data: other.data.into(),
}
}
}
impl From<&'_ ImageView<'_>> for ArcImage {
fn from(other: &ImageView) -> Self {
Self {
info: other.info,
data: other.data.into(),
}
}
}
impl From<ImageView<'_>> for Image {
fn from(other: ImageView) -> Self {
Self::Box(BoxImage::from(other))
}
}
impl From<&'_ ImageView<'_>> for Image {
fn from(other: &ImageView) -> Self {
Self::Box(BoxImage::from(other))
}
}
impl From<BoxImage> for ArcImage {
fn from(other: BoxImage) -> Self {
Self {
info: other.info,
data: other.data.into(),
}
}
}
impl From<BoxImage> for Image {
fn from(other: BoxImage) -> Self {
Self::Box(other)
}
}
impl From<ArcImage> for Image {
fn from(other: ArcImage) -> Self {
Self::Arc(other)
}
}
impl From<Box<dyn AsImageView + Send>> for Image {
fn from(other: Box<dyn AsImageView + Send>) -> Self {
Self::BoxDyn(other)
}
}
impl From<Arc<dyn AsImageView + Sync + Send>> for Image {
fn from(other: Arc<dyn AsImageView + Sync + Send>) -> Self {
Self::ArcDyn(other)
}
}
impl<T> From<Box<T>> for Image
where
T: AsImageView + Send + 'static,
{
fn from(other: Box<T>) -> Self {
Self::BoxDyn(other)
}
}
impl<T> From<Arc<T>> for Image
where
T: AsImageView + Send + Sync + 'static,
{
fn from(other: Arc<T>) -> Self {
Self::ArcDyn(other)
}
}