use core::fmt::Debug;
use super::{
into_component_slice, into_component_slice_mut, try_from_component_slice,
try_from_component_slice_mut, ArrayCast, SliceCastError,
};
pub trait AsComponents<C: ?Sized> {
fn as_components(&self) -> &C;
}
pub trait AsComponentsMut<C: ?Sized> {
fn as_components_mut(&mut self) -> &mut C;
}
macro_rules! impl_as_components {
($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
$(
impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsComponents<[T]> for $owning
where
C: ArrayCast<Array = [T; N]>,
{
#[inline]
fn as_components(&self) -> &[T] {
into_component_slice(self.as_ref())
}
}
impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsComponentsMut<[T]> for $owning
where
C: ArrayCast<Array = [T; N]>,
{
#[inline]
fn as_components_mut(&mut self) -> &mut [T] {
into_component_slice_mut(self.as_mut())
}
}
)*
};
}
impl_as_components!([C], [C; M] where (const M: usize));
#[cfg(feature = "alloc")]
impl_as_components!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);
pub trait TryComponentsAs<C: ?Sized> {
type Error;
fn try_components_as(&self) -> Result<&C, Self::Error>;
}
pub trait TryComponentsAsMut<C: ?Sized> {
type Error;
fn try_components_as_mut(&mut self) -> Result<&mut C, Self::Error>;
}
macro_rules! impl_try_components_as {
($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
$(
impl<'a, T, C, const N: usize $(, $($ty_input)+)?> TryComponentsAs<[C]> for $owning
where
C: ArrayCast<Array = [T; N]>,
{
type Error = SliceCastError;
#[inline]
fn try_components_as(&self) -> Result<&[C], Self::Error> {
try_from_component_slice(self.as_ref())
}
}
impl<'a, T, C, const N: usize $(, $($ty_input)+)?> TryComponentsAsMut<[C]> for $owning
where
C: ArrayCast<Array = [T; N]>,
{
type Error = SliceCastError;
#[inline]
fn try_components_as_mut(&mut self) -> Result<&mut [C], Self::Error> {
try_from_component_slice_mut(self.as_mut())
}
}
)*
};
}
impl_try_components_as!([T], [T; M] where (const M: usize));
#[cfg(feature = "alloc")]
impl_try_components_as!(alloc::boxed::Box<[T]>, alloc::vec::Vec<T>);
pub trait ComponentsAs<C: ?Sized> {
fn components_as(&self) -> &C;
}
impl<T, C> ComponentsAs<C> for T
where
T: TryComponentsAs<C> + ?Sized,
T::Error: Debug,
C: ?Sized,
{
fn components_as(&self) -> &C {
self.try_components_as().unwrap()
}
}
pub trait ComponentsAsMut<C: ?Sized> {
fn components_as_mut(&mut self) -> &mut C;
}
impl<T, C> ComponentsAsMut<C> for T
where
T: TryComponentsAsMut<C> + ?Sized,
T::Error: Debug,
C: ?Sized,
{
fn components_as_mut(&mut self) -> &mut C {
self.try_components_as_mut().unwrap()
}
}
#[cfg(test)]
mod test {
use crate::Srgb;
use super::{
AsComponents, AsComponentsMut, ComponentsAs, ComponentsAsMut, TryComponentsAs,
TryComponentsAsMut,
};
#[test]
fn as_components() {
let slice: &[Srgb<u8>] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
let slice_mut: &mut [Srgb<u8>] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
let mut slice_box: Box<[Srgb<u8>]> =
vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice();
let mut vec: Vec<Srgb<u8>> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
let mut array: [Srgb<u8>; 2] = [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
let _: &[u8] = slice.as_components();
let _: &[u8] = slice_box.as_components();
let _: &[u8] = vec.as_components();
let _: &[u8] = array.as_components();
let _: &mut [u8] = slice_mut.as_components_mut();
let _: &mut [u8] = slice_box.as_components_mut();
let _: &mut [u8] = vec.as_components_mut();
let _: &mut [u8] = array.as_components_mut();
}
#[test]
fn try_components_as() {
let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
let _: &[Srgb<u8>] = slice.try_components_as().unwrap();
let _: &[Srgb<u8>] = slice_box.try_components_as().unwrap();
let _: &[Srgb<u8>] = vec.try_components_as().unwrap();
let _: &[Srgb<u8>] = array.try_components_as().unwrap();
let _: &mut [Srgb<u8>] = slice_mut.try_components_as_mut().unwrap();
let _: &mut [Srgb<u8>] = slice_box.try_components_as_mut().unwrap();
let _: &mut [Srgb<u8>] = vec.try_components_as_mut().unwrap();
let _: &mut [Srgb<u8>] = array.try_components_as_mut().unwrap();
}
#[test]
fn components_as() {
let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
let _: &[Srgb<u8>] = slice.components_as();
let _: &[Srgb<u8>] = slice_box.components_as();
let _: &[Srgb<u8>] = vec.components_as();
let _: &[Srgb<u8>] = array.components_as();
let _: &mut [Srgb<u8>] = slice_mut.components_as_mut();
let _: &mut [Srgb<u8>] = slice_box.components_as_mut();
let _: &mut [Srgb<u8>] = vec.components_as_mut();
let _: &mut [Srgb<u8>] = array.components_as_mut();
}
}