Skip to content

Commit

Permalink
Merge pull request #373 from Ogeon/alloc_and_any_features_in_tests
Browse files Browse the repository at this point in the history
Add an "alloc" feature and make tests work with any feature combination
  • Loading branch information
Ogeon authored Jan 28, 2024
2 parents 919049c + 6d96f73 commit 4b17a15
Show file tree
Hide file tree
Showing 54 changed files with 1,526 additions and 1,299 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- uses: dtolnay/[email protected]
with:
components: clippy
- uses: taiki-e/install-action@cargo-hack
- name: Minimal check
run: cargo clippy -v -p palette --no-default-features --features std
- name: find-crate check
Expand All @@ -33,9 +34,7 @@ jobs:
- name: Test all features
run: cargo test -v -p palette --all-features
- name: Test each feature
shell: bash
working-directory: palette
run: bash ../scripts/test_features.sh
run: cargo hack test --tests --feature-powerset --ignore-private --skip default,find-crate --optional-deps libm --depth 2
integration_tests:
name: integration tests
strategy:
Expand Down Expand Up @@ -63,8 +62,13 @@ jobs:
with:
toolchain: ${{ matrix.toolchain }}
components: clippy
- uses: taiki-e/install-action@cargo-hack
- name: Check all features
run: cargo clippy -v -p palette --all-features
- name: Check each feature with libm
run: cargo hack clippy --each-feature --ignore-private --features libm --skip default,find-crate --ignore-unknown-features
- name: Check each feature with std
run: cargo hack clippy --each-feature --ignore-private --features std --skip default,find-crate --optional-deps libm --ignore-unknown-features
no_std:
name: "Test #[no_std]"
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ description = "Benchmark crate for palette."
repository = "https://github.com/Ogeon/palette"
license = "MIT OR Apache-2.0"
edition = "2018"
publish = false

[[bench]]
path = "benches/cie.rs"
Expand Down
1 change: 1 addition & 0 deletions integration_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ description = "Integration test crate for palette."
repository = "https://github.com/Ogeon/palette"
license = "MIT OR Apache-2.0"
edition = "2018"
publish = false

[[example]]
name = "issue_283"
Expand Down
1 change: 1 addition & 0 deletions no_std_test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ description = "Test crate for #[no_std]."
repository = "https://github.com/Ogeon/palette"
license = "MIT OR Apache-2.0"
edition = "2018"
publish = false

[[bin]]
name = "no_std_test"
Expand Down
4 changes: 2 additions & 2 deletions palette/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ named_from_str = ["named", "phf"]
named = []
random = ["rand"]
serializing = ["serde", "std"]
#ignore in feature test
find-crate = ["palette_derive/find-crate"]
std = ["approx?/std"]
std = ["alloc", "approx?/std"]
alloc = []

[lib]
bench = false
Expand Down
5 changes: 3 additions & 2 deletions palette/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ These features are enabled by default:

* `"named"` - Enables color constants, located in the `named` module.
* `"named_from_str"` - Enables `named::from_str`, which maps name strings to colors.
* `"std"` - Enables use of the standard library.
* `"std"` - Enables use of the standard library. Also enables `"alloc"`.
* `"alloc"` - Enables implementations for allocating types, such as `Vec` or `Box`.
* `"approx"` - Enables approximate comparison using [`approx`].

These features are disabled by default:
Expand All @@ -55,7 +56,7 @@ These features are disabled by default:

### Using palette in an embedded environment

Palette supports `#![no_std]` environments by disabling the `"std"` feature. It uses [`libm`] to provide the floating-point operations that are typically in `std`. However, serializing with `serde` is not available without the standard library.
Palette supports `#![no_std]` environments by disabling the `"std"` feature. It uses [`libm`], via the `"libm"` feature, to provide the floating-point operations that are typically in `std`, and the `"alloc"` feature to provide features that use allocating types. However, serializing with `serde` is not available without the standard library.

## Examples

Expand Down
4 changes: 2 additions & 2 deletions palette/src/alpha/alpha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1240,8 +1240,8 @@ mod test {

#[test]
fn check_min_max_components() {
assert_relative_eq!(Rgba::<Srgb>::min_alpha(), 0.0);
assert_relative_eq!(Rgba::<Srgb>::max_alpha(), 1.0);
assert_eq!(Rgba::<Srgb>::min_alpha(), 0.0);
assert_eq!(Rgba::<Srgb>::max_alpha(), 1.0);
}

#[cfg(feature = "serializing")]
Expand Down
2 changes: 2 additions & 0 deletions palette/src/blend/test.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg(feature = "approx")]

use crate::{
blend::{Blend, BlendWith, Compose},
LinSrgb, LinSrgba,
Expand Down
54 changes: 30 additions & 24 deletions palette/src/cast/array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use core::mem::{transmute_copy, ManuallyDrop};

#[cfg(feature = "alloc")]
use alloc::{boxed::Box, vec::Vec};

pub use palette_derive::ArrayCast;

use crate::ArrayExt;
Expand Down Expand Up @@ -958,7 +961,7 @@ where
/// let color2 = Box::new(Srgb::new(23u8, 198, 76));
/// let array2 = <Box<[_; 3]>>::from(color2);
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn into_array_box<T>(value: Box<T>) -> Box<T::Array>
where
Expand Down Expand Up @@ -1000,7 +1003,7 @@ where
/// let array2 = Box::new([23, 198, 76]);
/// let color2 = <Box<Srgb<u8>>>::from(array2);
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn from_array_box<T>(value: Box<T::Array>) -> Box<T>
where
Expand Down Expand Up @@ -1030,7 +1033,7 @@ where
/// vec![[64, 139, 10], [93, 18, 214]].into_boxed_slice()
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn into_array_slice_box<T>(values: Box<[T]>) -> Box<[T::Array]>
where
Expand All @@ -1053,7 +1056,7 @@ where
/// vec![64, 139, 10, 93, 18, 214].into_boxed_slice()
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn into_component_slice_box<T>(values: Box<[T]>) -> Box<[<T::Array as ArrayExt>::Item]>
where
Expand All @@ -1076,7 +1079,7 @@ where
/// vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].into_boxed_slice()
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn from_array_slice_box<T>(values: Box<[T::Array]>) -> Box<[T]>
where
Expand Down Expand Up @@ -1116,7 +1119,7 @@ where
/// let components = vec![64, 139, 10, 93, 18, 214, 0, 123].into_boxed_slice();
/// cast::from_component_slice_box::<Srgb<u8>>(components);
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn from_component_slice_box<T>(values: Box<[<T::Array as ArrayExt>::Item]>) -> Box<[T]>
where
Expand Down Expand Up @@ -1162,7 +1165,7 @@ where
/// unreachable!();
/// }
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn try_from_component_slice_box<T>(
values: Box<[<T::Array as ArrayExt>::Item]>,
Expand Down Expand Up @@ -1191,7 +1194,7 @@ where
/// vec![[64, 139, 10], [93, 18, 214]]
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn into_array_vec<T>(values: Vec<T>) -> Vec<T::Array>
where
Expand Down Expand Up @@ -1223,7 +1226,7 @@ where
/// vec![64, 139, 10, 93, 18, 214]
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn into_component_vec<T>(values: Vec<T>) -> Vec<<T::Array as ArrayExt>::Item>
where
Expand Down Expand Up @@ -1257,7 +1260,7 @@ where
/// vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
/// )
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn from_array_vec<T>(values: Vec<T::Array>) -> Vec<T>
where
Expand Down Expand Up @@ -1316,7 +1319,7 @@ where
/// components.reserve_exact(2); // Not a multiple of 3
/// cast::from_component_vec::<Srgb<u8>>(components);
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn from_component_vec<T>(values: Vec<<T::Array as ArrayExt>::Item>) -> Vec<T>
where
Expand Down Expand Up @@ -1376,7 +1379,7 @@ where
/// unreachable!();
/// }
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn try_from_component_vec<T>(
values: Vec<<T::Array as ArrayExt>::Item>,
Expand Down Expand Up @@ -1419,7 +1422,7 @@ where
/// Map values of color A to values of color B without creating a new `Vec`.
///
/// This uses the guarantees of [`ArrayCast`] to reuse the allocation.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn map_vec_in_place<A, B, F>(values: Vec<A>, mut map: F) -> Vec<B>
where
Expand Down Expand Up @@ -1453,7 +1456,7 @@ where
/// Map values of color A to values of color B without creating a new `Box<[B]>`.
///
/// This uses the guarantees of [`ArrayCast`] to reuse the allocation.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[inline]
pub fn map_slice_box_in_place<A, B, F>(values: Box<[A]>, mut map: F) -> Box<[B]>
where
Expand Down Expand Up @@ -1499,20 +1502,20 @@ impl std::error::Error for SliceCastError {}

/// The error type returned when casting a boxed slice of components fails.
#[derive(Clone, PartialEq, Eq)]
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub struct BoxedSliceCastError<T> {
/// The original values.
pub values: Box<[T]>,
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T> core::fmt::Debug for BoxedSliceCastError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("BoxedSliceCastError").finish()
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T> core::fmt::Display for BoxedSliceCastError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("could not convert boxed component slice to colors")
Expand All @@ -1524,7 +1527,7 @@ impl<T> std::error::Error for BoxedSliceCastError<T> {}

/// The error type returned when casting a `Vec` of components fails.
#[derive(Clone, PartialEq, Eq)]
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub struct VecCastError<T> {
/// The type of error that occurred.
pub kind: VecCastErrorKind,
Expand All @@ -1533,7 +1536,7 @@ pub struct VecCastError<T> {
pub values: Vec<T>,
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T> core::fmt::Debug for VecCastError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("VecCastError")
Expand All @@ -1542,7 +1545,7 @@ impl<T> core::fmt::Debug for VecCastError<T> {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T> core::fmt::Display for VecCastError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("could not convert component vector to colors")
Expand All @@ -1554,7 +1557,7 @@ impl<T> std::error::Error for VecCastError<T> {}

/// The type of error that is returned when casting a `Vec` of components.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub enum VecCastErrorKind {
/// The type of error returned when the length of a `Vec` didn't match the
/// requirements.
Expand All @@ -1567,9 +1570,10 @@ pub enum VecCastErrorKind {

#[cfg(test)]
mod test {
#[cfg(feature = "alloc")]
use crate::{LinSrgb, Srgb};

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[test]
fn array_vec_len_cap() {
let mut original = vec![
Expand All @@ -1596,11 +1600,12 @@ mod test {
assert_eq!(colors.capacity(), 8);
}

#[cfg(feature = "alloc")]
#[test]
fn map_vec_in_place() {
fn do_things(rgb: Srgb) -> LinSrgb {
let mut linear = rgb.into_linear();
std::mem::swap(&mut linear.red, &mut linear.blue);
core::mem::swap(&mut linear.red, &mut linear.blue);
linear
}

Expand All @@ -1615,11 +1620,12 @@ mod test {
)
}

#[cfg(feature = "alloc")]
#[test]
fn map_slice_box_in_place() {
fn do_things(rgb: Srgb) -> LinSrgb {
let mut linear = rgb.into_linear();
std::mem::swap(&mut linear.red, &mut linear.blue);
core::mem::swap(&mut linear.red, &mut linear.blue);
linear
}

Expand Down
8 changes: 4 additions & 4 deletions palette/src/cast/as_arrays_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ macro_rules! impl_as_arrays {

impl_as_arrays!([C], [C; M] where (const M: usize));

#[cfg(feature = "std")]
impl_as_arrays!(Box<[C]>, Vec<C>);
#[cfg(feature = "alloc")]
impl_as_arrays!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);

/// Trait for casting a reference to collection of arrays into a reference to
/// collection of colors without copying.
Expand Down Expand Up @@ -167,8 +167,8 @@ macro_rules! impl_arrays_as {

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(feature = "alloc")]
impl_arrays_as!(alloc::boxed::Box<[[T; N]]>, alloc::vec::Vec<[T; N]>);

#[cfg(test)]
mod test {
Expand Down
8 changes: 4 additions & 4 deletions palette/src/cast/as_components_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ macro_rules! impl_as_components {

impl_as_components!([C], [C; M] where (const M: usize));

#[cfg(feature = "std")]
impl_as_components!(Box<[C]>, Vec<C>);
#[cfg(feature = "alloc")]
impl_as_components!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);

/// Trait for trying to cast a reference to collection of color components into
/// a reference to collection of colors without copying.
Expand Down Expand Up @@ -221,8 +221,8 @@ macro_rules! impl_try_components_as {

impl_try_components_as!([T], [T; M] where (const M: usize));

#[cfg(feature = "std")]
impl_try_components_as!(Box<[T]>, Vec<T>);
#[cfg(feature = "alloc")]
impl_try_components_as!(alloc::boxed::Box<[T]>, alloc::vec::Vec<T>);

/// Trait for casting a reference to collection of color components into a
/// reference to collection of colors without copying.
Expand Down
Loading

0 comments on commit 4b17a15

Please sign in to comment.