diff --git a/palette/README.md b/palette/README.md index 2ac4e4663..f4709e077 100644 --- a/palette/README.md +++ b/palette/README.md @@ -92,13 +92,13 @@ A longer and more advanced example that shows how to implement the conversion tr When working with image or pixel buffers, or any color type that can be converted to a slice of components (ex. `&[u8]`), the `cast` module provides traits and functions for turning them into slices of Palette colors without cloning the whole buffer: ```rust -use palette::{cast::ComponentsInto, Srgb}; +use palette::{cast::ComponentsAsMut, Srgb}; // The input to this function could be data from an image file or // maybe a texture in a game. fn swap_red_and_blue(my_rgb_image: &mut [u8]) { // Convert `my_rgb_image` into `&mut [Srgb]` without copying. - let my_rgb_image: &mut [Srgb] = my_rgb_image.components_into(); + let my_rgb_image: &mut [Srgb] = my_rgb_image.components_as_mut(); for color in my_rgb_image { std::mem::swap(&mut color.red, &mut color.blue); @@ -152,13 +152,17 @@ This image shows the transition from the color to `new_color` in HSL and HSV: In addition to the operator traits, the SVG blend and composition functions have also been implemented. ```rust -use palette::{blend::Compose, cast::ComponentsInto, Srgb, WithAlpha}; +use palette::{ + blend::Compose, + cast::{ComponentsAs, ComponentsAsMut}, + Srgb, WithAlpha, +}; // The input to this function could be data from image files. fn alpha_blend_images(image1: &mut [u8], image2: &[u8]) { // Convert the images into `&mut [Srgb]` and `&[Srgb]` without copying. - let image1: &mut [Srgb] = image1.components_into(); - let image2: &[Srgb] = image2.components_into(); + let image1: &mut [Srgb] = image1.components_as_mut(); + let image2: &[Srgb] = image2.components_as(); for (color1, color2) in image1.iter_mut().zip(image2) { // Convert the colors to linear floating point format and give them transparency values. diff --git a/palette/examples/readme_examples.rs b/palette/examples/readme_examples.rs index 7b04d9ce2..c59338859 100644 --- a/palette/examples/readme_examples.rs +++ b/palette/examples/readme_examples.rs @@ -26,13 +26,13 @@ fn converting() { } fn pixels_and_buffers() { - use palette::{cast::ComponentsInto, Srgb}; + use palette::{cast::ComponentsAsMut, Srgb}; // The input to this function could be data from an image file or // maybe a texture in a game. fn swap_red_and_blue(my_rgb_image: &mut [u8]) { // Convert `my_rgb_image` into `&mut [Srgb]` without copying. - let my_rgb_image: &mut [Srgb] = my_rgb_image.components_into(); + let my_rgb_image: &mut [Srgb] = my_rgb_image.components_as_mut(); for color in my_rgb_image { std::mem::swap(&mut color.red, &mut color.blue); @@ -91,13 +91,17 @@ fn color_operations_1() { } fn color_operations_2() { - use palette::{blend::Compose, cast::ComponentsInto, Srgb, WithAlpha}; + use palette::{ + blend::Compose, + cast::{ComponentsAs, ComponentsAsMut}, + Srgb, WithAlpha, + }; // The input to this function could be data from image files. fn alpha_blend_images(image1: &mut [u8], image2: &[u8]) { // Convert the images into `&mut [Srgb]` and `&[Srgb]` without copying. - let image1: &mut [Srgb] = image1.components_into(); - let image2: &[Srgb] = image2.components_into(); + let image1: &mut [Srgb] = image1.components_as_mut(); + let image2: &[Srgb] = image2.components_as(); for (color1, color2) in image1.iter_mut().zip(image2) { // Convert the colors to linear floating point format and give them transparency values. diff --git a/palette/examples/struct_of_arrays.rs b/palette/examples/struct_of_arrays.rs index d79a5e5a8..c65960a32 100644 --- a/palette/examples/struct_of_arrays.rs +++ b/palette/examples/struct_of_arrays.rs @@ -1,11 +1,11 @@ -use palette::{cast::ComponentsInto, color_difference::EuclideanDistance, IntoColor, Oklab, Srgb}; +use palette::{cast::ComponentsAs, color_difference::EuclideanDistance, IntoColor, Oklab, Srgb}; fn main() { let image = image::open("example-data/input/fruits.png") .expect("could not open 'example-data/input/fruits.png'") .to_rgb8(); - let image: &[Srgb] = image.as_raw().components_into(); + let image: &[Srgb] = image.components_as(); // Convert and collect the colors in a struct-of-arrays (SoA) format, where // each component is a Vec of all the pixels' component values. diff --git a/palette/src/cast.rs b/palette/src/cast.rs index b77adf906..a51eb6af8 100644 --- a/palette/src/cast.rs +++ b/palette/src/cast.rs @@ -33,13 +33,13 @@ //! same after casting. //! //! ``` -//! use palette::{cast::{self, ArraysInto}, Srgb, IntoColor}; +//! use palette::{cast::{self, ArraysAsMut}, Srgb, IntoColor}; //! //! let color = cast::from_array::>([23, 198, 76]).into_linear(); //! // Note: `Srgb::::from([23, 198, 76])` works too. //! -//! let buffer = &mut [[64, 139, 10], [93, 18, 214]]; -//! let color_buffer: &mut [Srgb] = buffer.arrays_into(); +//! let mut buffer = [[64, 139, 10], [93, 18, 214]]; +//! let color_buffer: &mut [Srgb] = buffer.arrays_as_mut(); //! //! for destination in color_buffer { //! let linear_dst = destination.into_linear::(); @@ -47,7 +47,7 @@ //! } //! ``` //! -//! Trying to cast an array of the wrong size will not compile: +//! Trying to cast a single array of the wrong size will not compile: //! //! ```compile_fail //! use palette::{cast, Srgb}; @@ -68,35 +68,37 @@ //! or multiplying the length. //! //! ``` -//! use palette::{cast::{self, TryFromComponents}, Srgb}; +//! use palette::{cast::{self, TryComponentsAs}, Srgb}; //! -//! let correct_buffer = &[64, 139, 10, 93, 18, 214]; -//! assert!(<&[Srgb]>::try_from_components(correct_buffer).is_ok()); +//! let correct_buffer = [64, 139, 10, 93, 18, 214]; +//! let should_be_ok: Result<&[Srgb], _> = correct_buffer.try_components_as(); +//! assert!(should_be_ok.is_ok()); //! -//! let incorrect_buffer = &[64, 139, 10, 93, 18, 214, 198, 76]; -//! assert!(<&[Srgb]>::try_from_components(incorrect_buffer).is_err()); +//! let incorrect_buffer = [64, 139, 10, 93, 18, 214, 198, 76]; +//! let should_be_err: Result<&[Srgb], _> = incorrect_buffer.try_components_as(); +//! assert!(should_be_err.is_err()); //! ``` //! //! An alternative, for when the length can be trusted to be correct, is to use -//! the `ComponentsInto::components_into` and `FromComponents::from_components` -//! methods, or the `from_component_*` functions, that panic on error. +//! methods without the `try_*` prefix, such as `ComponentsAs::components_as`, +//! or the `from_component_*` functions, that panic on error. //! //! This works: //! //! ``` -//! use palette::{cast::ComponentsInto, Srgb}; +//! use palette::{cast::ComponentsAs, Srgb}; //! -//! let correct_buffer = &[64, 139, 10, 93, 18, 214]; -//! let color_buffer: &[Srgb] = correct_buffer.components_into(); +//! let correct_buffer = [64, 139, 10, 93, 18, 214]; +//! let color_buffer: &[Srgb] = correct_buffer.components_as(); //! ``` //! //! But this panics: //! //! ```should_panic -//! use palette::{cast::ComponentsInto, Srgb}; +//! use palette::{cast::ComponentsAs, Srgb}; //! -//! let incorrect_buffer = &[64, 139, 10, 93, 18, 214, 198, 76]; -//! let color_buffer: &[Srgb] = incorrect_buffer.components_into(); +//! let incorrect_buffer = [64, 139, 10, 93, 18, 214, 198, 76]; +//! let color_buffer: &[Srgb] = incorrect_buffer.components_as(); //! ``` //! //! ## Casting Single Colors @@ -128,10 +130,10 @@ //! //! ``` //! // `PackedArgb` is an alias for `Packed`. -//! use palette::{rgb::PackedArgb, cast::ComponentsInto, Srgba}; +//! use palette::{rgb::PackedArgb, cast::ComponentsAs, Srgba}; //! -//! let components = &[1.0f32, 0.8, 0.2, 0.3, 1.0, 0.5, 0.7, 0.6]; -//! let colors: &[PackedArgb<_>] = components.components_into(); +//! let components = [1.0f32, 0.8, 0.2, 0.3, 1.0, 0.5, 0.7, 0.6]; +//! let colors: &[PackedArgb<_>] = components.components_as(); //! //! // Notice how the alpha values have moved from the beginning to the end: //! assert_eq!(Srgba::from(colors[0]), Srgba::new(0.8, 0.2, 0.3, 1.0)); @@ -152,10 +154,10 @@ //! //! ``` //! // `PackedArgb` is an alias for `Packed`. -//! use palette::{rgb::PackedArgb, cast::UintsInto, Srgba}; +//! use palette::{rgb::PackedArgb, cast::UintsAs, Srgba}; //! -//! let raw = &[0xFF7F0080u32, 0xFF60BBCC]; -//! let colors: &[PackedArgb] = raw.uints_into(); +//! let raw = [0xFF7F0080u32, 0xFF60BBCC]; +//! let colors: &[PackedArgb] = raw.uints_as(); //! //! assert_eq!(colors.len(), 2); //! assert_eq!(Srgba::from(colors[0]), Srgba::new(0x7F, 0x00, 0x80, 0xFF)); @@ -163,6 +165,9 @@ //! ``` mod array; +mod as_arrays_traits; +mod as_components_traits; +mod as_uints_traits; mod from_into_arrays_traits; mod from_into_components_traits; mod from_into_uints_traits; @@ -170,6 +175,7 @@ mod packed; mod uint; pub use self::{ - array::*, from_into_arrays_traits::*, from_into_components_traits::*, - from_into_uints_traits::*, packed::*, uint::*, + array::*, as_arrays_traits::*, as_components_traits::*, as_uints_traits::*, + from_into_arrays_traits::*, from_into_components_traits::*, from_into_uints_traits::*, + packed::*, uint::*, }; diff --git a/palette/src/cast/as_arrays_traits.rs b/palette/src/cast/as_arrays_traits.rs new file mode 100644 index 000000000..15445f243 --- /dev/null +++ b/palette/src/cast/as_arrays_traits.rs @@ -0,0 +1,217 @@ +use super::{ + from_array_slice, from_array_slice_mut, into_array_slice, into_array_slice_mut, ArrayCast, +}; + +/// Trait for casting a reference to a collection of colors into a reference to +/// a collection of arrays without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsArrays, Srgb}; +/// +/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let slice: &[_] = &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// +/// assert_eq!(array.as_arrays(), &[[64, 139, 10], [93, 18, 214]]); +/// assert_eq!(slice.as_arrays(), &[[64, 139, 10], [93, 18, 214]]); +/// assert_eq!(vec.as_arrays(), &[[64, 139, 10], [93, 18, 214]]); +/// ``` +pub trait AsArrays { + /// Cast this collection of colors into a collection of arrays. + fn as_arrays(&self) -> &A; +} + +/// Trait for casting a mutable reference to a collection of colors into a +/// mutable reference to a collection of arrays without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsArraysMut, Srgb}; +/// +/// let mut array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let slice_mut: &mut [_] = &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let mut vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// +/// assert_eq!(array.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]); +/// assert_eq!(slice_mut.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]); +/// assert_eq!(vec.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]); +/// ``` +pub trait AsArraysMut { + /// Cast this collection of colors into a mutable collection of arrays. + fn as_arrays_mut(&mut self) -> &mut A; +} + +macro_rules! impl_as_arrays { + ($($owning:ty $(where ($($ty_input:tt)+))?),*) => { + $( + impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsArrays<[[T; N]]> for $owning + where + C: ArrayCast, + { + #[inline] + fn as_arrays(&self) -> &[[T; N]] { + into_array_slice(self.as_ref()) + } + } + + impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsArraysMut<[[T; N]]> for $owning + where + C: ArrayCast, + { + #[inline] + fn as_arrays_mut(&mut self) -> &mut [[T; N]] { + into_array_slice_mut(self.as_mut()) + } + } + )* + }; +} + +impl_as_arrays!([C], [C; M] where (const M: usize)); + +#[cfg(feature = "std")] +impl_as_arrays!(Box<[C]>, Vec); + +/// Trait for casting a reference to collection of arrays into a reference to +/// collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::ArraysAs, Srgb}; +/// +/// let array: [_; 2] = [[64, 139, 10], [93, 18, 214]]; +/// let slice: &[_] = &[[64, 139, 10], [93, 18, 214]]; +/// let vec: Vec<_> = vec![[64, 139, 10], [93, 18, 214]]; +/// +/// let colors: &[Srgb] = array.arrays_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &[Srgb] = slice.arrays_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &[Srgb] = vec.arrays_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// ``` +pub trait ArraysAs { + /// Cast this collection of arrays into a collection of colors. + fn arrays_as(&self) -> &C; +} + +/// Trait for casting a mutable reference to collection of arrays into a mutable +/// reference to collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::ArraysAsMut, Srgb}; +/// +/// let mut array: [_; 2] = [[64, 139, 10], [93, 18, 214]]; +/// let slice_mut: &mut [_] = &mut [[64, 139, 10], [93, 18, 214]]; +/// let mut vec: Vec<_> = vec![[64, 139, 10], [93, 18, 214]]; +/// +/// let colors: &mut [Srgb] = array.arrays_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &mut [Srgb] = slice_mut.arrays_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &mut [Srgb] = vec.arrays_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// ``` +pub trait ArraysAsMut { + /// Cast this collection of arrays into a mutable collection of colors. + fn arrays_as_mut(&mut self) -> &mut C; +} + +macro_rules! impl_arrays_as { + ($($owning:ty $(where ($($ty_input:tt)+))?),*) => { + $( + impl<'a, T, C, const N: usize $(, $($ty_input)+)?> ArraysAs<[C]> for $owning + where + C: ArrayCast, + { + #[inline] + fn arrays_as(&self) -> &[C] { + from_array_slice(self.as_ref()) + } + } + + impl<'a, T, C, const N: usize $(, $($ty_input)+)?> ArraysAsMut<[C]> for $owning + where + C: ArrayCast, + { + #[inline] + fn arrays_as_mut(&mut self) -> &mut [C] { + from_array_slice_mut(self.as_mut()) + } + } + )* + }; +} + +impl_arrays_as!([[T; N]], [[T; N]; M] where (const M: usize)); + +#[cfg(feature = "std")] +impl_arrays_as!(Box<[[T; N]]>, Vec<[T; N]>); + +#[cfg(test)] +mod test { + use crate::Srgb; + + use super::{ArraysAs, ArraysAsMut, AsArrays, AsArraysMut}; + + #[test] + fn as_arrays() { + let slice: &[Srgb] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let slice_mut: &mut [Srgb] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let mut slice_box: Box<[Srgb]> = + vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice(); + let mut vec: Vec> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let mut array: [Srgb; 2] = [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + + let _: &[[u8; 3]] = slice.as_arrays(); + let _: &[[u8; 3]] = slice_box.as_arrays(); + let _: &[[u8; 3]] = vec.as_arrays(); + let _: &[[u8; 3]] = array.as_arrays(); + + let _: &mut [[u8; 3]] = slice_mut.as_arrays_mut(); + let _: &mut [[u8; 3]] = slice_box.as_arrays_mut(); + let _: &mut [[u8; 3]] = vec.as_arrays_mut(); + let _: &mut [[u8; 3]] = array.as_arrays_mut(); + } + + #[test] + fn arrays_as() { + let slice: &[[u8; 3]] = &[[1, 2, 3], [4, 5, 6]]; + let slice_mut: &mut [[u8; 3]] = &mut [[1, 2, 3], [4, 5, 6]]; + let mut slice_box: Box<[[u8; 3]]> = vec![[1, 2, 3], [4, 5, 6]].into_boxed_slice(); + let mut vec: Vec<[u8; 3]> = vec![[1, 2, 3], [4, 5, 6]]; + let mut array: [[u8; 3]; 2] = [[1, 2, 3], [4, 5, 6]]; + + let _: &[Srgb] = slice.arrays_as(); + let _: &[Srgb] = slice_box.arrays_as(); + let _: &[Srgb] = vec.arrays_as(); + let _: &[Srgb] = array.arrays_as(); + + let _: &mut [Srgb] = slice_mut.arrays_as_mut(); + let _: &mut [Srgb] = slice_box.arrays_as_mut(); + let _: &mut [Srgb] = vec.arrays_as_mut(); + let _: &mut [Srgb] = array.arrays_as_mut(); + } +} diff --git a/palette/src/cast/as_components_traits.rs b/palette/src/cast/as_components_traits.rs new file mode 100644 index 000000000..656018cee --- /dev/null +++ b/palette/src/cast/as_components_traits.rs @@ -0,0 +1,411 @@ +use core::fmt::Debug; + +use super::{ + into_component_slice, into_component_slice_mut, try_from_component_slice, + try_from_component_slice_mut, ArrayCast, SliceCastError, +}; + +/// Trait for casting a reference to a collection of colors into a reference to +/// a collection of color components without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsComponents, Srgb}; +/// +/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let slice: &[_] = &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// +/// assert_eq!(array.as_components(), &[64, 139, 10, 93, 18, 214]); +/// assert_eq!(slice.as_components(), &[64, 139, 10, 93, 18, 214]); +/// assert_eq!(vec.as_components(), &[64, 139, 10, 93, 18, 214]); +/// ``` +pub trait AsComponents { + /// Cast this collection of colors into a collection of color components. + fn as_components(&self) -> &C; +} + +/// Trait for casting a mutable reference to a collection of colors into a +/// mutable reference to a collection of color components without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsComponentsMut, Srgb}; +/// +/// let mut array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let slice_mut: &mut [_] = &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// let mut vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]; +/// +/// assert_eq!(array.as_components_mut(), &mut [64, 139, 10, 93, 18, 214]); +/// assert_eq!(slice_mut.as_components_mut(), &mut [64, 139, 10, 93, 18, 214]); +/// assert_eq!(vec.as_components_mut(), &mut [64, 139, 10, 93, 18, 214]); +/// ``` +pub trait AsComponentsMut { + /// Cast this collection of colors into a mutable collection of color + /// components. + 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, + { + #[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, + { + #[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 = "std")] +impl_as_components!(Box<[C]>, Vec); + +/// Trait for trying to cast a reference to collection of color components into +/// a reference to collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Errors +/// +/// The cast will return an error if the cast fails, such as when the length of +/// the input is not a multiple of the color's array length. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::TryComponentsAs, Srgb}; +/// +/// let array: [_; 6] = [64, 139, 10, 93, 18, 214]; +/// let slice: &[_] = &[64, 139, 10, 93, 18, 214]; +/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214]; +/// +/// let colors: Result<&[Srgb], _> = array.try_components_as(); +/// assert_eq!(colors, Ok(&[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// +/// let colors: Result<&[Srgb], _> = slice.try_components_as(); +/// assert_eq!(colors, Ok(&[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// +/// let colors: Result<&[Srgb], _> = vec.try_components_as(); +/// assert_eq!(colors, Ok(&[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// ``` +/// +/// This produces an error: +/// +/// ``` +/// use palette::{cast::TryComponentsAs, Srgb}; +/// +/// let components = [64, 139, 10, 93, 18]; // Not a multiple of 3 +/// let colors: Result<&[Srgb], _> = components.try_components_as(); +/// assert!(colors.is_err()); +/// ``` +pub trait TryComponentsAs { + /// The error for when `try_components_as` fails to cast. + type Error; + + /// Try to cast this collection of color components into a reference to a + /// collection of colors. + /// + /// Return an error if the conversion can't be done, such as when the number + /// of items in `self` isn't a multiple of the number of components in the + /// color type. + fn try_components_as(&self) -> Result<&C, Self::Error>; +} + +/// Trait for trying to cast a mutable reference to collection of color +/// components into a mutable reference to collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Errors +/// +/// The cast will return an error if the cast fails, such as when the length of +/// the input is not a multiple of the color's array length. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::TryComponentsAsMut, Srgb}; +/// +/// let mut array: [_; 6] = [64, 139, 10, 93, 18, 214]; +/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214]; +/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214]; +/// +/// let colors: Result<&mut [Srgb], _> = array.try_components_as_mut(); +/// assert_eq!(colors, Ok(&mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// +/// let colors: Result<&mut [Srgb], _> = slice_mut.try_components_as_mut(); +/// assert_eq!(colors, Ok(&mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// +/// let colors: Result<&mut [Srgb], _> = vec.try_components_as_mut(); +/// assert_eq!(colors, Ok(&mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)][..])); +/// ``` +/// +/// This produces an error: +/// +/// ``` +/// use palette::{cast::TryComponentsAsMut, Srgb}; +/// +/// let mut components = [64, 139, 10, 93, 18]; // Not a multiple of 3 +/// let colors: Result<&mut [Srgb], _> = components.try_components_as_mut(); +/// assert!(colors.is_err()); +/// ``` +pub trait TryComponentsAsMut { + /// The error for when `try_components_as_mut` fails to cast. + type Error; + + /// Try to cast this collection of color components into a mutable reference + /// to a collection of colors. + /// + /// Return an error if the conversion can't be done, such as when the number + /// of items in `self` isn't a multiple of the number of components in the + /// color type. + 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, + { + 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, + { + 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 = "std")] +impl_try_components_as!(Box<[T]>, Vec); + +/// Trait for casting a reference to collection of color components into a +/// reference to collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Panics +/// +/// The cast will panic if the cast fails, such as when the length of the input +/// is not a multiple of the color's array length. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::ComponentsAs, Srgb}; +/// +/// let array: [_; 6] = [64, 139, 10, 93, 18, 214]; +/// let slice: &[_] = &[64, 139, 10, 93, 18, 214]; +/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214]; +/// +/// let colors: &[Srgb] = array.components_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &[Srgb] = slice.components_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &[Srgb] = vec.components_as(); +/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// ``` +/// +/// This panics: +/// +/// ```should_panic +/// use palette::{cast::ComponentsAs, Srgb}; +/// +/// let components = [64, 139, 10, 93, 18, 214, 0, 123]; // Not a multiple of 3 +/// let colors: &[Srgb] = components.components_as(); +/// ``` +pub trait ComponentsAs { + /// Cast this collection of color components into a reference to a + /// collection of colors. + /// + /// ## Panics + /// If the conversion can't be done, such as when the number of items in + /// `self` isn't a multiple of the number of components in the color type. + fn components_as(&self) -> &C; +} + +impl ComponentsAs for T +where + T: TryComponentsAs + ?Sized, + T::Error: Debug, + C: ?Sized, +{ + fn components_as(&self) -> &C { + self.try_components_as().unwrap() + } +} + +/// Trait for casting a mutable reference to collection of color components into +/// a mutable reference to collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Panics +/// +/// The cast will panic if the cast fails, such as when the length of the input +/// is not a multiple of the color's array length. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::ComponentsAsMut, Srgb}; +/// +/// let mut array: [_; 6] = [64, 139, 10, 93, 18, 214]; +/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214]; +/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214]; +/// +/// let colors: &mut [Srgb] = array.components_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &mut [Srgb] = slice_mut.components_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// +/// let colors: &mut [Srgb] = vec.components_as_mut(); +/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); +/// ``` +/// +/// This panics: +/// +/// ```should_panic +/// use palette::{cast::ComponentsAsMut, Srgb}; +/// +/// let mut components = [64, 139, 10, 93, 18, 214, 0, 123]; // Not a multiple of 3 +/// let colors: &mut [Srgb] = components.components_as_mut(); +/// ``` +pub trait ComponentsAsMut { + /// Cast this collection of color components into a mutable reference to a + /// collection of colors. + /// + /// ## Panics + /// If the conversion can't be done, such as when the number of items in + /// `self` isn't a multiple of the number of components in the color type. + fn components_as_mut(&mut self) -> &mut C; +} + +impl ComponentsAsMut for T +where + T: TryComponentsAsMut + ?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] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let slice_mut: &mut [Srgb] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let mut slice_box: Box<[Srgb]> = + vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice(); + let mut vec: Vec> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)]; + let mut array: [Srgb; 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 = vec![1, 2, 3, 4, 5, 6]; + let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6]; + + let _: &[Srgb] = slice.try_components_as().unwrap(); + let _: &[Srgb] = slice_box.try_components_as().unwrap(); + let _: &[Srgb] = vec.try_components_as().unwrap(); + let _: &[Srgb] = array.try_components_as().unwrap(); + + let _: &mut [Srgb] = slice_mut.try_components_as_mut().unwrap(); + let _: &mut [Srgb] = slice_box.try_components_as_mut().unwrap(); + let _: &mut [Srgb] = vec.try_components_as_mut().unwrap(); + let _: &mut [Srgb] = 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 = vec![1, 2, 3, 4, 5, 6]; + let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6]; + + let _: &[Srgb] = slice.components_as(); + let _: &[Srgb] = slice_box.components_as(); + let _: &[Srgb] = vec.components_as(); + let _: &[Srgb] = array.components_as(); + + let _: &mut [Srgb] = slice_mut.components_as_mut(); + let _: &mut [Srgb] = slice_box.components_as_mut(); + let _: &mut [Srgb] = vec.components_as_mut(); + let _: &mut [Srgb] = array.components_as_mut(); + } +} diff --git a/palette/src/cast/as_uints_traits.rs b/palette/src/cast/as_uints_traits.rs new file mode 100644 index 000000000..5c0f4a464 --- /dev/null +++ b/palette/src/cast/as_uints_traits.rs @@ -0,0 +1,272 @@ +use super::{from_uint_slice, from_uint_slice_mut, into_uint_slice, into_uint_slice_mut, UintCast}; + +/// Trait for casting a reference to a collection of colors into a reference to +/// a collection of unsigned integers without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsUints, rgb::PackedArgb, Srgba}; +/// +/// let array: [PackedArgb; 2] = [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// let slice: &[PackedArgb] = &[ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// let vec: Vec = vec![ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// +/// assert_eq!(array.as_uints(), &[0xFF17C64C, 0xFF5D12D6]); +/// assert_eq!(slice.as_uints(), &[0xFF17C64C, 0xFF5D12D6]); +/// assert_eq!(vec.as_uints(), &[0xFF17C64C, 0xFF5D12D6]); +/// ``` +pub trait AsUints { + /// Cast this collection of colors into a collection of unsigned integers. + fn as_uints(&self) -> &A; +} + +/// Trait for casting a mutable reference to a collection of colors into a +/// mutable reference to a collection of unsigned integers without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::AsUintsMut, rgb::PackedArgb, Srgba}; +/// +/// let mut array: [PackedArgb; 2] = [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// let slice_mut: &mut [PackedArgb] = &mut [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// let mut vec: Vec = vec![ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ]; +/// +/// assert_eq!(array.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]); +/// assert_eq!(slice_mut.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]); +/// assert_eq!(vec.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]); +/// ``` +pub trait AsUintsMut { + /// Cast this collection of colors into a mutable collection of unsigned integers. + fn as_uints_mut(&mut self) -> &mut A; +} + +macro_rules! impl_as_uints { + ($($owning:ty $(where ($($ty_input:tt)+))?),*) => { + $( + impl<'a, C $(, $($ty_input)+)?> AsUints<[C::Uint]> for $owning + where + C: UintCast, + { + #[inline] + fn as_uints(&self) -> &[C::Uint] { + into_uint_slice(self.as_ref()) + } + } + + impl<'a, C $(, $($ty_input)+)?> AsUintsMut<[C::Uint]> for $owning + where + C: UintCast, + { + #[inline] + fn as_uints_mut(&mut self) -> &mut [C::Uint] { + into_uint_slice_mut(self.as_mut()) + } + } + )* + }; +} + +impl_as_uints!([C], [C; N] where (const N: usize)); + +#[cfg(feature = "std")] +impl_as_uints!(Box<[C]>, Vec); + +/// Trait for casting a reference to a collection of unsigned integers into a +/// reference to a collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::UintsAs, rgb::PackedArgb, Srgba}; +/// +/// let array: [_; 2] = [0xFF17C64C, 0xFF5D12D6]; +/// let slice: &[_] = &[0xFF17C64C, 0xFF5D12D6]; +/// let vec: Vec<_> = vec![0xFF17C64C, 0xFF5D12D6]; +/// +/// let colors: &[PackedArgb] = array.uints_as(); +/// assert_eq!( +/// colors, +/// &[ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// +/// let colors: &[PackedArgb] = slice.uints_as(); +/// assert_eq!( +/// colors, +/// &[ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// +/// let colors: &[PackedArgb] = vec.uints_as(); +/// assert_eq!( +/// colors, +/// &[ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// ``` +pub trait UintsAs { + /// Cast this collection of unsigned integers into a collection of colors. + fn uints_as(&self) -> &C; +} + +/// Trait for casting a mutable reference to a collection of unsigned integers +/// into a mutable reference to a collection of colors without copying. +/// +/// This trait is meant as a more convenient alternative to the free functions +/// in [`cast`][crate::cast], to allow method chaining among other things. +/// +/// ## Examples +/// +/// ``` +/// use palette::{cast::UintsAsMut, rgb::PackedArgb, Srgba}; +/// +/// let mut array: [_; 2] = [0xFF17C64C, 0xFF5D12D6]; +/// let slice_mut: &mut [_] = &mut [0xFF17C64C, 0xFF5D12D6]; +/// let mut vec: Vec<_> = vec![0xFF17C64C, 0xFF5D12D6]; +/// +/// let colors: &mut [PackedArgb] = array.uints_as_mut(); +/// assert_eq!( +/// colors, +/// &mut [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// +/// let colors: &mut [PackedArgb] = slice_mut.uints_as_mut(); +/// assert_eq!( +/// colors, +/// &mut [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// +/// let colors: &mut [PackedArgb] = vec.uints_as_mut(); +/// assert_eq!( +/// colors, +/// &mut [ +/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(), +/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into() +/// ] +/// ); +/// ``` +pub trait UintsAsMut { + /// Cast this collection of unsigned integers into a mutable collection of colors. + fn uints_as_mut(&mut self) -> &mut C; +} + +macro_rules! impl_uints_as { + ($($owning:ty $(where ($($ty_input:tt)+))?),*) => { + $( + impl<'a, C $(, $($ty_input)+)?> UintsAs<[C]> for $owning + where + C: UintCast, + { + #[inline] + fn uints_as(&self) -> &[C] { + from_uint_slice(self.as_ref()) + } + } + + impl<'a, C $(, $($ty_input)+)?> UintsAsMut<[C]> for $owning + where + C: UintCast, + { + #[inline] + fn uints_as_mut(&mut self) -> &mut [C] { + from_uint_slice_mut(self.as_mut()) + } + } + )* + }; +} + +impl_uints_as!([C::Uint], [C::Uint; N] where (const N: usize)); + +#[cfg(feature = "std")] +impl_uints_as!(Box<[C::Uint]>, Vec); + +#[cfg(test)] +mod test { + use crate::{rgb::PackedRgba, Srgba}; + + use super::{AsUints, AsUintsMut, UintsAs, UintsAsMut}; + + #[test] + fn as_uints() { + let slice: &[PackedRgba] = &[Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()]; + let slice_mut: &mut [PackedRgba] = + &mut [Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()]; + let mut slice_box: Box<[PackedRgba]> = + vec![Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()].into_boxed_slice(); + let mut vec: Vec = + vec![Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()]; + let mut array: [PackedRgba; 2] = + [Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()]; + + let _: &[u32] = slice.as_uints(); + let _: &[u32] = slice_box.as_uints(); + let _: &[u32] = vec.as_uints(); + let _: &[u32] = array.as_uints(); + + let _: &mut [u32] = slice_mut.as_uints_mut(); + let _: &mut [u32] = slice_box.as_uints_mut(); + let _: &mut [u32] = vec.as_uints_mut(); + let _: &mut [u32] = array.as_uints_mut(); + } + + #[test] + fn uints_as() { + let slice: &[u32] = &[0x01020304, 0x05060708]; + let slice_mut: &mut [u32] = &mut [0x01020304, 0x05060708]; + let mut slice_box: Box<[u32]> = vec![0x01020304, 0x05060708].into_boxed_slice(); + let mut vec: Vec = vec![0x01020304, 0x05060708]; + let mut array: [u32; 2] = [0x01020304, 0x05060708]; + + let _: &[PackedRgba] = slice.uints_as(); + let _: &[PackedRgba] = slice_box.uints_as(); + let _: &[PackedRgba] = vec.uints_as(); + let _: &[PackedRgba] = array.uints_as(); + + let _: &mut [PackedRgba] = slice_mut.uints_as_mut(); + let _: &mut [PackedRgba] = slice_box.uints_as_mut(); + let _: &mut [PackedRgba] = vec.uints_as_mut(); + let _: &mut [PackedRgba] = array.uints_as_mut(); + } +} diff --git a/palette/src/cast/from_into_arrays_traits.rs b/palette/src/cast/from_into_arrays_traits.rs index 126353d68..f9c66079f 100644 --- a/palette/src/cast/from_into_arrays_traits.rs +++ b/palette/src/cast/from_into_arrays_traits.rs @@ -62,8 +62,7 @@ use super::{from_array_slice_box, from_array_vec, into_array_slice_box, into_arr /// ); /// ``` pub trait FromArrays { - /// Cast a collection of arrays into an collection of colors of type - /// `Self::Color`. + /// Cast a collection of arrays into an collection of colors. fn from_arrays(arrays: A) -> Self; } @@ -323,7 +322,7 @@ where /// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]); /// ``` pub trait ArraysInto { - /// Cast this collection of arrays into a collection of colors of type `C`. + /// Cast this collection of arrays into a collection of colors. fn arrays_into(self) -> C; } diff --git a/palette/src/cast/from_into_components_traits.rs b/palette/src/cast/from_into_components_traits.rs index aa219d538..3962ce23f 100644 --- a/palette/src/cast/from_into_components_traits.rs +++ b/palette/src/cast/from_into_components_traits.rs @@ -87,11 +87,11 @@ pub trait TryFromComponents: Sized { type Error; /// Try to cast a collection of color components into an collection of - /// colors of type `Self::Color`. + /// colors. /// /// Return an error if the conversion can't be done, such as when the number /// of items in `components` isn't a multiple of the number of components in - /// `Self::Color`. + /// the color type. fn try_from_components(components: C) -> Result; } @@ -245,13 +245,12 @@ where /// <&[Srgb]>::from_components(components); /// ``` pub trait FromComponents { - /// Cast a collection of color components into an collection of colors of - /// type `Self::Color`. + /// Cast a collection of color components into an collection of colors. /// /// ## Panics /// If the conversion can't be done, such as when the number of items in - /// `components` isn't a multiple of the number of components in - /// `Self::Color`. + /// `components` isn't a multiple of the number of components in the color + /// type. fn from_components(components: C) -> Self; } @@ -408,8 +407,7 @@ where /// assert_eq!(<&mut [_]>::components_from(&mut vec), [64, 139, 10, 93, 18, 214]); /// ``` pub trait ComponentsFrom { - /// Cast a collection of colors of type `C` into a collection of color - /// components. + /// Cast a collection of colors into a collection of color components. fn components_from(colors: C) -> Self; } @@ -498,10 +496,11 @@ pub trait TryComponentsInto: Sized { type Error; /// Try to cast this collection of color components into a collection of - /// colors of type `C`. + /// colors. /// /// Return an error if the conversion can't be done, such as when the number - /// of items in `self` isn't a multiple of the number of components in `C`. + /// of items in `self` isn't a multiple of the number of components in the + /// color type. fn try_components_into(self) -> Result; } @@ -563,12 +562,11 @@ pub trait TryComponentsInto: Sized { /// let colors: &[Srgb] = components.components_into(); /// ``` pub trait ComponentsInto { - /// Cast this collection of color components into a collection of colors of - /// type `C`. + /// Cast this collection of color components into a collection of colors. /// /// ## Panics /// If the conversion can't be done, such as when the number of items in - /// `self` isn't a multiple of the number of components in `C`. + /// `self` isn't a multiple of the number of components in the color type. fn components_into(self) -> C; } diff --git a/palette/src/cast/packed.rs b/palette/src/cast/packed.rs index 8b22652a2..9ec0f5c27 100644 --- a/palette/src/cast/packed.rs +++ b/palette/src/cast/packed.rs @@ -12,10 +12,10 @@ use super::ArrayCast; /// /// ``` /// // `PackedArgb` is an alias for `Packed`. -/// use palette::{rgb::PackedArgb, cast::UintsInto}; +/// use palette::{rgb::PackedArgb, cast::UintsAs}; /// -/// let raw = &[0x7F0080u32, 0x60BBCC]; -/// let colors: &[PackedArgb] = raw.uints_into(); +/// let raw = [0x7F0080u32, 0x60BBCC]; +/// let colors: &[PackedArgb] = raw.uints_as(); /// /// assert_eq!(colors.len(), 2); /// assert_eq!(colors[0].color, 0x7F0080); diff --git a/palette/src/convert.rs b/palette/src/convert.rs index 7434493c2..e4b52b408 100644 --- a/palette/src/convert.rs +++ b/palette/src/convert.rs @@ -138,7 +138,7 @@ //! #[macro_use] //! extern crate approx; //! -//! use palette::cast::{ComponentsInto, ArrayCast}; +//! use palette::cast::{ComponentsAs, ArrayCast}; //! use palette::rgb::{Rgb, RgbSpace, RgbStandard}; //! use palette::encoding::Linear; //! use palette::white_point::D65; @@ -199,7 +199,7 @@ //! 0.5, //! 0.25, //! ]; -//! let buffer: &[Bgr<_>] = (&buffer).components_into(); +//! let buffer: &[Bgr<_>] = buffer.components_as(); //! let hsv: Hsv<_, f64> = buffer[1].into_color(); //! //! assert_relative_eq!(hsv, Hsv::new(90.0, 1.0, 0.5)); diff --git a/palette/src/lib.rs b/palette/src/lib.rs index 75fe7d0c9..84b652138 100644 --- a/palette/src/lib.rs +++ b/palette/src/lib.rs @@ -186,12 +186,12 @@ //! to Palette colors: //! //! ```rust -//! # let mut image_buffer: &mut Vec = &mut vec![]; -//! use palette::{Srgb, cast::ComponentsInto}; +//! # let mut image_buffer: Vec = vec![]; +//! use palette::{Srgb, cast::ComponentsAsMut}; //! -//! // This works for any color type (even non-RGB) that can have the +//! // This works for any color type (not only RGB) that can have the //! // buffer element type as component. -//! let color_buffer: &mut [Srgb] = image_buffer.components_into(); +//! let color_buffer: &mut [Srgb] = image_buffer.components_as_mut(); //! ``` //! //! * If you are getting your colors from the GPU, in a game or other graphical