diff --git a/README.md b/README.md index acab7b8c0..e8630ebb6 100644 --- a/README.md +++ b/README.md @@ -20,16 +20,27 @@ Add the following lines to your `Cargo.toml` file: palette = "0.4" ``` -### Optional Features +### Features These features are enabled by default: * `"named"` - Enables color constants, located in the `named` module. -* `"named_from_str"` - Enables the `named::from_str`, which maps name string to colors. +* `"named_from_str"` - Enables the `named::from_str`, which maps name string to colors. This requires the standard library. +* `"std"` - Enables use of the standard library. These features are disabled by default: -* `"serde"` - Enables color serializing and deserializing. +* `"serializing"` - Enables color serializing and deserializing using `serde`. + +### Without the standard library + +Here is an example `Cargo.toml` entry for using palette on `#![no_std]`: + +```toml +[dependencies.palette] +version = "0.4" +default-features = false +``` ## It's Never "Just RGB" @@ -113,6 +124,18 @@ This library is only meant for color manipulation and conversion. It's not a ful [pixel_module]: https://ogeon.github.io/docs/palette/master/palette/pixel/index.html +## Using palette in an embedded environment + +Palette supports `#![no_std]` environments by disabling the `"std"` feature. However, there are some things that are unavailable without the standard library: + +* Gradients are unavailable, because they depend heavily on Vectors +* The `"named_from_str"` feature requires the standard library as well +* Serialization using `serde` is unavailable + +It uses [`libm`] to provide the floating-point operations that are typically in `std`. + +[`libm`]: https://github.com/japaric/libm + ## Contributing All sorts of contributions are welcome, no matter how huge or tiny, so take a look at [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, if you are interested. diff --git a/palette/Cargo.toml b/palette/Cargo.toml index 28a9f77ae..f7457fc1d 100644 --- a/palette/Cargo.toml +++ b/palette/Cargo.toml @@ -13,24 +13,26 @@ license = "MIT OR Apache-2.0" build = "build/main.rs" [features] -default = ["named_from_str"] -named_from_str = ["named", "phf", "phf_codegen"] +default = ["named_from_str", "std"] +named_from_str = ["named", "phf", "phf_codegen", "std"] named = [] +std = ["approx/std", "num-traits/std"] +serializing = ["serde", "std"] #internal strict = [] [dependencies] palette_derive = {version = "0.4.1", path = "../palette_derive"} -num-traits = "0.2" -approx = "0.2" +num-traits = {version = "0.2", default-features = false} +approx = {version = "0.2", default-features = false} +libm = "0.1.2" [dependencies.phf] version = "0.7" optional = true [dependencies.serde] -#feature version = "1" features = ["serde_derive"] optional = true diff --git a/palette/README.md b/palette/README.md index 706342307..32bb56dd2 100644 --- a/palette/README.md +++ b/palette/README.md @@ -20,16 +20,27 @@ Add the following lines to your `Cargo.toml` file: palette = "0.4" ``` -### Optional Features +### Features These features are enabled by default: * `"named"` - Enables color constants, located in the `named` module. -* `"named_from_str"` - Enables the `named::from_str`, which maps name string to colors. +* `"named_from_str"` - Enables the `named::from_str`, which maps name string to colors. This requires the standard library. +* `"std"` - Enables use of the standard library. These features are disabled by default: -* `"serde"` - Enables color serializing and deserializing. +* `"serializing"` - Enables color serializing and deserializing using `serde`. + +### Without the standard library + +Here is an example `Cargo.toml` entry for using palette on `#![no_std]`: + +```toml +[dependencies.palette] +version = "0.4" +default-features = false +``` ## It's Never "Just RGB" @@ -109,12 +120,22 @@ The RGB gradient goes through gray, while the HSV gradients changes only the hue ## What It Isn't -This library is only meant for color manipulation and conversion. It's not a fully features image manipulation library. It will only handle colors, and not whole images. - -These are meant to work as bridges between Palette and other graphical libraries, but it has been limited only focus on single pixel operations to keep the scope at a manageable size. +This library is only meant for color manipulation and conversion. It's not a fully features image manipulation library. It will only handle colors, and not whole images. There are features that are meant to work as bridges between Palette and other graphical libraries, but the main features are limited to only focus on single pixel operations, to keep the scope at a manageable size. [pixel_module]: https://ogeon.github.io/docs/palette/master/palette/pixel/index.html +## Using palette in an embedded environment + +Palette supports `#![no_std]` environments by disabling the `"std"` feature. However, there are some things that are unavailable without the standard library: + +* Gradients are unavailable, because they depend heavily on Vectors +* The `"named_from_str"` feature requires the standard library as well +* Serialization using `serde` is unavailable + +It uses [`libm`] to provide the floating-point operations that are typically in `std`. + +[`libm`]: https://github.com/japaric/libm + ## Contributing All sorts of contributions are welcome, no matter how huge or tiny, so take a look at [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, if you are interested. diff --git a/palette/build/named.rs b/palette/build/named.rs index 83e93b586..306c899d2 100644 --- a/palette/build/named.rs +++ b/palette/build/named.rs @@ -32,7 +32,7 @@ pub fn build() { .expect(&format!("couldn't get blue for {}", name)); writeln!(writer, "\n///
", name).unwrap(); - writeln!(writer, "pub const {}: ::rgb::Srgb = ::rgb::Srgb {{ red: {}, green: {}, blue: {}, standard: ::std::marker::PhantomData }};", name.to_uppercase(), red, green, blue).unwrap(); + writeln!(writer, "pub const {}: ::rgb::Srgb = ::rgb::Srgb {{ red: {}, green: {}, blue: {}, standard: ::core::marker::PhantomData }};", name.to_uppercase(), red, green, blue).unwrap(); entries.push((name.to_owned(), name.to_uppercase())); } diff --git a/palette/examples/gradient.rs b/palette/examples/gradient.rs index 91af39d38..3bd722071 100644 --- a/palette/examples/gradient.rs +++ b/palette/examples/gradient.rs @@ -1,11 +1,17 @@ extern crate image; extern crate palette; -use palette::{Gradient, Lch, LinSrgb, Pixel, Srgb}; - -use image::{GenericImage, RgbImage}; +#[cfg(not(feature = "std"))] +fn main() { + println!("You can't use gradients without the standard library"); +} +#[cfg(feature = "std")] fn main() { + use palette::{Gradient, Lch, LinSrgb, Pixel, Srgb}; + + use image::{GenericImage, RgbImage}; + //A gradient of evenly spaced colors let grad1 = Gradient::new(vec![ LinSrgb::new(1.0, 0.1, 0.1), diff --git a/palette/examples/readme_examples.rs b/palette/examples/readme_examples.rs index 905ba26e5..1f1400559 100644 --- a/palette/examples/readme_examples.rs +++ b/palette/examples/readme_examples.rs @@ -4,7 +4,9 @@ extern crate palette; use image::{GenericImage, RgbImage}; -use palette::{Gradient, LinSrgb, Mix, Pixel, Srgb}; +use palette::{Pixel, Srgb}; +#[cfg(feature = "std")] +use palette::{Gradient, LinSrgb, Mix}; mod color_spaces { use palette::{Hue, Lch, LinSrgb, Srgb}; @@ -44,6 +46,7 @@ mod manipulation { } } +#[cfg(feature = "std")] mod gradients { use palette::{Gradient, Hsv, LinSrgb}; use display_gradients; @@ -81,6 +84,7 @@ fn display_colors(filename: &str, colors: &[Srgb]) { } } +#[cfg(feature = "std")] fn display_gradients + Clone, B: Mix + Clone>( filename: &str, grad1: Gradient, @@ -127,5 +131,6 @@ fn display_gradients + Clone, B: Mix + Clone> fn main() { color_spaces::run(); manipulation::run(); + #[cfg(feature = "std")] gradients::run(); } diff --git a/palette/src/alpha.rs b/palette/src/alpha.rs index fe0f20120..101130b8a 100644 --- a/palette/src/alpha.rs +++ b/palette/src/alpha.rs @@ -1,7 +1,7 @@ -use std::ops::{Add, Deref, DerefMut, Div, Mul, Sub}; -use std::fmt; +use core::ops::{Add, Deref, DerefMut, Div, Mul, Sub}; +use core::fmt; -use num_traits::Float; +use float::Float; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; @@ -11,11 +11,11 @@ use encoding::pixel::RawPixel; ///An alpha component wrapper for colors. #[derive(Clone, Copy, Debug, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[repr(C)] pub struct Alpha { ///The color. - #[cfg_attr(feature = "serde", serde(flatten))] + #[cfg_attr(feature = "serializing", serde(flatten))] pub color: C, ///The transparency component. 0.0 is fully transparent and 1.0 is fully @@ -338,7 +338,7 @@ where C: fmt::LowerHex, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!( f, "{:0width$x}{:0width$x}", @@ -355,7 +355,7 @@ where C: fmt::UpperHex, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!( f, "{:0width$X}{:0width$X}", @@ -467,7 +467,7 @@ mod test { ); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Rgba::::new(0.3, 0.8, 0.1, 0.5)).unwrap(); @@ -478,7 +478,7 @@ mod test { ); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Rgba = diff --git a/palette/src/blend/blend.rs b/palette/src/blend/blend.rs index d67eb1803..1d3200f19 100644 --- a/palette/src/blend/blend.rs +++ b/palette/src/blend/blend.rs @@ -1,4 +1,7 @@ -use num_traits::{Float, One, Zero}; +use num_traits::{One, Zero}; +use float::Float; +#[cfg(feature = "libm_works")] +use num_traits::float::FloatCore; use {cast, clamp, ComponentWise}; use blend::{BlendFunction, PreAlpha}; diff --git a/palette/src/blend/equations.rs b/palette/src/blend/equations.rs index 5e267f6e2..b3b412ca5 100644 --- a/palette/src/blend/equations.rs +++ b/palette/src/blend/equations.rs @@ -1,4 +1,6 @@ -use num_traits::Float; +use float::Float; +#[cfg(feature = "libm_works")] +use num_traits::float::FloatCore; use {Blend, ComponentWise}; use blend::{BlendFunction, PreAlpha}; diff --git a/palette/src/blend/mod.rs b/palette/src/blend/mod.rs index 72c1b15c0..d675dde9e 100644 --- a/palette/src/blend/mod.rs +++ b/palette/src/blend/mod.rs @@ -36,7 +36,7 @@ //!which may result in loss of some color information in some cases. One such //!case is that a completely transparent resultant color will become black. -use num_traits::Float; +use float::Float; use ComponentWise; diff --git a/palette/src/blend/pre_alpha.rs b/palette/src/blend/pre_alpha.rs index ac1338eb7..43569f657 100644 --- a/palette/src/blend/pre_alpha.rs +++ b/palette/src/blend/pre_alpha.rs @@ -1,6 +1,6 @@ -use std::ops::{Add, Deref, DerefMut, Div, Mul, Sub}; +use core::ops::{Add, Deref, DerefMut, Div, Mul, Sub}; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; use {clamp, Alpha, Blend, ComponentWise, Mix, Pixel}; use encoding::pixel::RawPixel; @@ -27,11 +27,11 @@ use encoding::pixel::RawPixel; ///Note that converting to and from premultiplied alpha will cause the alpha ///component to be clamped to [0.0, 1.0]. #[derive(Clone, Copy, PartialEq, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[repr(C)] pub struct PreAlpha { ///The premultiplied color components (`original.color * original.alpha`). - #[cfg_attr(feature = "serde", serde(flatten))] + #[cfg_attr(feature = "serializing", serde(flatten))] pub color: C, ///The transparency component. 0.0 is fully transparent and 1.0 is fully @@ -319,13 +319,13 @@ impl DerefMut for PreAlpha { } #[cfg(test)] -#[cfg(feature = "serde")] +#[cfg(feature = "serializing")] mod test { use super::PreAlpha; use rgb::Rgb; use encoding::Srgb; - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let color = PreAlpha { @@ -338,7 +338,7 @@ mod test { assert_eq!(serialized, r#"{"red":0.3,"green":0.8,"blue":0.1,"alpha":0.5}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let expected = PreAlpha { diff --git a/palette/src/chromatic_adaptation.rs b/palette/src/chromatic_adaptation.rs index be2a84263..ef8488cfa 100644 --- a/palette/src/chromatic_adaptation.rs +++ b/palette/src/chromatic_adaptation.rs @@ -22,7 +22,7 @@ //!//Should print {x: 0.257963, y: 0.139776,z: 0.058825} //!println!("{:?}", c) //!``` -use num_traits::Float; +use float::Float; use {cast, Component, FromColor, IntoColor, Xyz}; use white_point::WhitePoint; diff --git a/palette/src/convert.rs b/palette/src/convert.rs index 29b055ae0..446e82cae 100644 --- a/palette/src/convert.rs +++ b/palette/src/convert.rs @@ -1,7 +1,6 @@ -use num_traits::Float; +use float::Float; -use std::error::Error; -use std::fmt::{self, Debug, Display, Formatter}; +use core::fmt::{self, Display, Formatter}; use {Component, Limited, Hsl, Hsv, Hwb, Lab, Lch, Xyz, Yxy}; use white_point::{D65, WhitePoint}; use rgb::{Rgb, RgbSpace}; @@ -102,7 +101,6 @@ use encoding::Linear; /// ```rust /// #[macro_use] /// extern crate palette; -/// extern crate num_traits; /// #[macro_use] /// extern crate approx; /// @@ -110,7 +108,7 @@ use encoding::Linear; /// use palette::rgb::{Rgb, RgbSpace}; /// use palette::encoding::Linear; /// use palette::white_point::D65; -/// use num_traits::Float; +/// use palette::float::Float; /// /// /// sRGB, but with a reversed memory layout. /// #[derive(PartialEq, Debug, FromColor, Pixel)] @@ -349,7 +347,6 @@ where /// ```rust /// #[macro_use] /// extern crate palette; -/// extern crate num_traits; /// #[macro_use] /// extern crate approx; /// @@ -357,7 +354,7 @@ where /// use palette::rgb::{Rgb, RgbSpace}; /// use palette::encoding::Linear; /// use palette::white_point::D65; -/// use num_traits::Float; +/// use palette::float::Float; /// /// /// sRGB, but with a reversed memory layout. /// #[derive(Copy, Clone, IntoColor, Pixel)] @@ -521,7 +518,8 @@ impl OutOfBounds { } } -impl Error for OutOfBounds { +#[cfg(feature = "std")] +impl ::std::error::Error for OutOfBounds { fn description(&self) -> &str { "Color conversion is out of bounds" } @@ -761,8 +759,8 @@ impl_into_color_rgb!(Hwb, from_hwb); #[cfg(test)] mod tests { - use std::marker::PhantomData; - use num_traits::Float; + use core::marker::PhantomData; + use float::Float; use Component; use Linear; use rgb::{Rgb, RgbSpace}; diff --git a/palette/src/encoding/gamma.rs b/palette/src/encoding/gamma.rs index 900da9877..e270167dd 100644 --- a/palette/src/encoding/gamma.rs +++ b/palette/src/encoding/gamma.rs @@ -1,8 +1,8 @@ //! Gamma encoding. -use std::marker::PhantomData; +use core::marker::PhantomData; -use num_traits::Float; +use float::Float; use cast; use rgb::{RgbSpace, RgbStandard}; diff --git a/palette/src/encoding/linear.rs b/palette/src/encoding/linear.rs index 255b46b11..28fbea974 100644 --- a/palette/src/encoding/linear.rs +++ b/palette/src/encoding/linear.rs @@ -1,8 +1,8 @@ //! Linear encoding -use std::marker::PhantomData; +use core::marker::PhantomData; -use num_traits::Float; +use float::Float; use rgb::{RgbSpace, RgbStandard}; use luma::LumaStandard; use encoding::TransferFn; diff --git a/palette/src/encoding/mod.rs b/palette/src/encoding/mod.rs index 244bdc92f..a8ebba26f 100644 --- a/palette/src/encoding/mod.rs +++ b/palette/src/encoding/mod.rs @@ -1,6 +1,6 @@ //! Various encoding traits, types and standards. -use num_traits::Float; +use float::Float; pub use self::srgb::Srgb; pub use self::gamma::{F2p2, Gamma}; diff --git a/palette/src/encoding/pixel/mod.rs b/palette/src/encoding/pixel/mod.rs index 63c8cfe75..cfd396969 100644 --- a/palette/src/encoding/pixel/mod.rs +++ b/palette/src/encoding/pixel/mod.rs @@ -124,13 +124,13 @@ pub unsafe trait Pixel: Sized { #[inline] fn into_raw>(self) -> P { assert_eq!(P::CHANNELS, Self::CHANNELS); - assert_eq!(::std::mem::size_of::

(), ::std::mem::size_of::()); - assert_eq!(::std::mem::align_of::

(), ::std::mem::align_of::()); + assert_eq!(::core::mem::size_of::

(), ::core::mem::size_of::()); + assert_eq!(::core::mem::align_of::

(), ::core::mem::align_of::()); - let converted = unsafe { ::std::ptr::read(&self as *const Self as *const P) }; + let converted = unsafe { ::core::ptr::read(&self as *const Self as *const P) }; // Just to be sure... - ::std::mem::forget(self); + ::core::mem::forget(self); converted } @@ -168,7 +168,7 @@ pub unsafe trait Pixel: Sized { fn from_raw_slice(slice: &[T]) -> &[Self] { assert_eq!(slice.len() % Self::CHANNELS, 0); let new_length = slice.len() / Self::CHANNELS; - unsafe { ::std::slice::from_raw_parts(slice.as_ptr() as *const Self, new_length) } + unsafe { ::core::slice::from_raw_parts(slice.as_ptr() as *const Self, new_length) } } /// Cast a mutable slice of raw color components to a mutable slice of colors. @@ -193,7 +193,7 @@ pub unsafe trait Pixel: Sized { fn from_raw_slice_mut(slice: &mut [T]) -> &mut [Self] { assert_eq!(slice.len() % Self::CHANNELS, 0); let new_length = slice.len() / Self::CHANNELS; - unsafe { ::std::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut Self, new_length) } + unsafe { ::core::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut Self, new_length) } } /// Cast a slice of colors to a slice of raw color components. @@ -210,7 +210,7 @@ pub unsafe trait Pixel: Sized { #[inline] fn into_raw_slice(slice: &[Self]) -> &[T] { let new_length = slice.len() * Self::CHANNELS; - unsafe { ::std::slice::from_raw_parts(slice.as_ptr() as *const T, new_length) } + unsafe { ::core::slice::from_raw_parts(slice.as_ptr() as *const T, new_length) } } /// Cast a mutable slice of colors to a mutable slice of raw color components. @@ -234,6 +234,6 @@ pub unsafe trait Pixel: Sized { #[inline] fn into_raw_slice_mut(slice: &mut [Self]) -> &mut [T] { let new_length = slice.len() * Self::CHANNELS; - unsafe { ::std::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut T, new_length) } + unsafe { ::core::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut T, new_length) } } } diff --git a/palette/src/encoding/pixel/raw.rs b/palette/src/encoding/pixel/raw.rs index 3389fb348..b1945b097 100644 --- a/palette/src/encoding/pixel/raw.rs +++ b/palette/src/encoding/pixel/raw.rs @@ -81,12 +81,12 @@ unsafe impl RawPixel for [T] { #[inline] unsafe fn from_raw_parts<'a>(pointer: *const T, length: usize) -> &'a Self { - ::std::slice::from_raw_parts(pointer, length) + ::core::slice::from_raw_parts(pointer, length) } #[inline] unsafe fn from_raw_parts_mut<'a>(pointer: *mut T, length: usize) -> &'a mut Self { - ::std::slice::from_raw_parts_mut(pointer, length) + ::core::slice::from_raw_parts_mut(pointer, length) } #[inline] diff --git a/palette/src/encoding/srgb.rs b/palette/src/encoding/srgb.rs index efb5dd8df..522a8ede1 100644 --- a/palette/src/encoding/srgb.rs +++ b/palette/src/encoding/srgb.rs @@ -1,6 +1,6 @@ //! The sRGB standard. -use num_traits::Float; +use float::Float; use rgb::{Primaries, RgbSpace, RgbStandard}; use luma::LumaStandard; diff --git a/palette/src/equality.rs b/palette/src/equality.rs index 5e6a57439..95de209dd 100644 --- a/palette/src/equality.rs +++ b/palette/src/equality.rs @@ -1,4 +1,4 @@ -use num_traits::Float; +use float::Float; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; diff --git a/palette/src/float.rs b/palette/src/float.rs new file mode 100644 index 000000000..e9b084d47 --- /dev/null +++ b/palette/src/float.rs @@ -0,0 +1,102 @@ +//! Floating point traits +//! +//! This module is work-around for the lack of floating point operations under +//! `#![no_std]`. If you haven't disabled the `std` feature, it just re-exports +//! `num_traits::Float`. +//! +//! However, without `std`, it's a custom trait with a subset of the methods +//! from `num_traits::Float`, implemented for `f32` and `f64` using [`libm`]. +//! +//! [`libm`]: https://github.com/japaric/libm + +pub use num_traits::Float; + +#[cfg(feature = "libm_works")] +pub use self::no_std_float_trait::Float; + +#[cfg(feature = "libm_works")] +mod no_std_float_trait { + extern crate libm; + use self::libm::{F32Ext, F64Ext}; + + use core::{f32, f64}; + use num_traits::float::FloatCore; + + /// This is the trait that represents a floating-point number under + /// `no_std`. It has a subset of the operations that are in + /// `num_traits::Float`. + /// For more documentation of specific functions in this trait, see the + /// [`num_traits::Float` docs][num_traits]. + /// + /// It's implemented for `f32` and `f64`. See the [module docs][module] for + /// details. + /// + /// # Compatibility between versions + /// + /// Because of the possibility of needing more floating point operations in + /// point releases, this trait is semver-exempt with respect to adding + /// new functions. (If you really need to implement it for your own + /// `MyFloat` type, pin a specific version in your `Cargo.toml`.) However, + /// removing methods from this trait will still be considered a + /// breaking change. + /// + /// [num_traits]: https://docs.rs/num-traits/0.2.5/num_traits/float/trait.Float.html + /// [module]: index.html + pub trait Float: FloatCore { + /// `x.sqrt()` computes the square root of `x`. + fn sqrt(self) -> Self; + /// `x.cbrt()` computes the cube root of `x`. + fn cbrt(self) -> Self; + /// `x.powf(y)` computes `x` to the power of `y`. + fn powf(self, other: Self) -> Self; + /// `x.sin()` computes the sine of `x` radians. + fn sin(self) -> Self; + /// `x.cos()` computes the cosine of `x` radians. + fn cos(self) -> Self; + /// `y.atan2(x)` computes the inverse tangent of `y / x`, in the + /// corresponding quadrant + fn atan2(self, other: Self) -> Self; + } + + impl Float for f32 { + fn sqrt(self) -> f32 { + F32Ext::cbrt(self) + } + fn cbrt(self) -> f32 { + F32Ext::sqrt(self) + } + fn powf(self, other: f32) -> f32 { + F32Ext::powf(self, other) + } + fn sin(self) -> f32 { + F32Ext::sin(self) + } + fn cos(self) -> f32 { + F32Ext::cos(self) + } + fn atan2(self, other: f32) -> f32 { + F32Ext::atan2(self, other) + } + } + + impl Float for f64 { + fn sqrt(self) -> f64 { + F64Ext::sqrt(self) + } + fn cbrt(self) -> f64 { + F64Ext::cbrt(self) + } + fn powf(self, other: f64) -> f64 { + F64Ext::powf(self, other) + } + fn sin(self) -> f64 { + F64Ext::sin(self) + } + fn cos(self) -> f64 { + F64Ext::cos(self) + } + fn atan2(self, other: f64) -> f64 { + F64Ext::atan2(self, other) + } + } +} diff --git a/palette/src/gradient.rs b/palette/src/gradient.rs index bffadbc86..504e097b9 100644 --- a/palette/src/gradient.rs +++ b/palette/src/gradient.rs @@ -1,6 +1,10 @@ //!Types for interpolation between multiple colors. +//! +//!This module is only available if the `std` feature is enabled (this is the +//!default). -use num_traits::{Float, One, Zero}; +use num_traits::{One, Zero}; +use float::Float; use std::cmp::max; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; diff --git a/palette/src/hsl.rs b/palette/src/hsl.rs index 325b7f35f..7ade6277b 100644 --- a/palette/src/hsl.rs +++ b/palette/src/hsl.rs @@ -1,9 +1,9 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; -use std::any::TypeId; -use std::marker::PhantomData; -use std::ops::{Add, Sub}; +use core::any::TypeId; +use core::marker::PhantomData; +use core::ops::{Add, Sub}; use encoding::pixel::RawPixel; use encoding::{Linear, Srgb}; @@ -29,7 +29,7 @@ pub type Hsla = Alpha, T>; ///See [HSV](struct.Hsv.html) for a very similar color space, with brightness /// instead of lightness. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_rgb_space = "S"] #[palette_white_point = "S::WhitePoint"] @@ -56,7 +56,7 @@ where ///The white point and RGB primaries this color is adapted to. The default ///is the sRGB standard. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub space: PhantomData, } @@ -652,7 +652,7 @@ mod test { raw_pixel_conversion_tests!(Hsl: hue, saturation, lightness); raw_pixel_conversion_fail_tests!(Hsl: hue, saturation, lightness); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Hsl::new(0.3, 0.8, 0.1)).unwrap(); @@ -663,7 +663,7 @@ mod test { ); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Hsl = diff --git a/palette/src/hsv.rs b/palette/src/hsv.rs index 0a1de52a2..26fca96ac 100644 --- a/palette/src/hsv.rs +++ b/palette/src/hsv.rs @@ -1,9 +1,9 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; -use std::any::TypeId; -use std::marker::PhantomData; -use std::ops::{Add, Sub}; +use core::any::TypeId; +use core::marker::PhantomData; +use core::ops::{Add, Sub}; use encoding::pixel::RawPixel; use encoding::{Linear, Srgb}; @@ -25,7 +25,7 @@ pub type Hsva = Alpha, T>; ///and white (100% R, 100% G, 100% B) has the same brightness (or value), but ///not the same lightness. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "S::WhitePoint"] #[palette_rgb_space = "S"] @@ -53,7 +53,7 @@ where ///The white point and RGB primaries this color is adapted to. The default ///is the sRGB standard. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub space: PhantomData, } @@ -663,7 +663,7 @@ mod test { raw_pixel_conversion_tests!(Hsv: hue, saturation, value); raw_pixel_conversion_fail_tests!(Hsv: hue, saturation, value); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Hsv::new(0.3, 0.8, 0.1)).unwrap(); @@ -671,7 +671,7 @@ mod test { assert_eq!(serialized, r#"{"hue":0.3,"saturation":0.8,"value":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Hsv = diff --git a/palette/src/hues.rs b/palette/src/hues.rs index 7839f3232..4df9f77cf 100644 --- a/palette/src/hues.rs +++ b/palette/src/hues.rs @@ -1,8 +1,8 @@ -use num_traits::Float; +use float::Float; -use std::f64::consts::PI; -use std::cmp::PartialEq; -use std::ops::{Add, Sub}; +use core::f64::consts::PI; +use core::cmp::PartialEq; +use core::ops::{Add, Sub}; use cast; @@ -16,7 +16,7 @@ macro_rules! make_hues { /// also have some surprising effects if it's expected to act as a /// linear number. #[derive(Clone, Copy, Debug, Default)] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[repr(C)] pub struct $name(T); @@ -314,7 +314,7 @@ mod test { } } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&RgbHue::from_degrees(10.2)).unwrap(); @@ -322,7 +322,7 @@ mod test { assert_eq!(serialized, "10.2"); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: RgbHue = ::serde_json::from_str("10.2").unwrap(); diff --git a/palette/src/hwb.rs b/palette/src/hwb.rs index c8ada0428..c04816c99 100644 --- a/palette/src/hwb.rs +++ b/palette/src/hwb.rs @@ -1,9 +1,9 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; -use std::any::TypeId; -use std::marker::PhantomData; -use std::ops::{Add, Sub}; +use core::any::TypeId; +use core::marker::PhantomData; +use core::ops::{Add, Sub}; use encoding::pixel::RawPixel; use encoding::Srgb; @@ -27,7 +27,7 @@ pub type Hwba = Alpha, T>; ///It is very intuitive for humans to use and many color-pickers are based on /// the HWB color system #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_rgb_space = "S"] #[palette_white_point = "S::WhitePoint"] @@ -59,7 +59,7 @@ where ///The white point and RGB primaries this color is adapted to. The default ///is the sRGB standard. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub space: PhantomData, } @@ -621,7 +621,7 @@ mod test { raw_pixel_conversion_tests!(Hwb: hue, whiteness, blackness); raw_pixel_conversion_fail_tests!(Hwb: hue, whiteness, blackness); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Hwb::new(0.3, 0.8, 0.1)).unwrap(); @@ -629,7 +629,7 @@ mod test { assert_eq!(serialized, r#"{"hue":0.3,"whiteness":0.8,"blackness":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Hwb = diff --git a/palette/src/lab.rs b/palette/src/lab.rs index a3f58d3d9..65ec364f6 100644 --- a/palette/src/lab.rs +++ b/palette/src/lab.rs @@ -1,7 +1,7 @@ -use num_traits::Float; +use float::Float; -use std::marker::PhantomData; -use std::ops::{Add, Div, Mul, Sub}; +use core::marker::PhantomData; +use core::ops::{Add, Div, Mul, Sub}; use encoding::pixel::RawPixel; use white_point::{D65, WhitePoint}; @@ -25,7 +25,7 @@ pub type Laba = Alpha, T>; ///The parameters of L\*a\*b\* are quite different, compared to many other /// color spaces, so manipulating them manually may be unintuitive. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "Wp"] #[palette_component = "T"] @@ -48,7 +48,7 @@ where ///The white point associated with the color's illuminant and observer. ///D65 for 2 degree observer is used by default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub white_point: PhantomData, } @@ -170,7 +170,7 @@ where let kappa: T = cast(841.0 / 108.0); let delta: T = cast(4.0 / 29.0); if c > epsilon { - c.powf(T::one() / cast(3.0)) + c.cbrt() } else { (kappa * c) + delta } @@ -547,7 +547,7 @@ mod test { raw_pixel_conversion_tests!(Lab: l, a, b); raw_pixel_conversion_fail_tests!(Lab: l, a, b); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Lab::new(0.3, 0.8, 0.1)).unwrap(); @@ -555,7 +555,7 @@ mod test { assert_eq!(serialized, r#"{"l":0.3,"a":0.8,"b":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Lab = ::serde_json::from_str(r#"{"l":0.3,"a":0.8,"b":0.1}"#).unwrap(); diff --git a/palette/src/lch.rs b/palette/src/lch.rs index c869efc93..c9386ecf0 100644 --- a/palette/src/lch.rs +++ b/palette/src/lch.rs @@ -1,7 +1,7 @@ -use num_traits::Float; +use float::Float; -use std::marker::PhantomData; -use std::ops::{Add, Sub}; +use core::marker::PhantomData; +use core::ops::{Add, Sub}; use encoding::pixel::RawPixel; use white_point::{D65, WhitePoint}; @@ -20,7 +20,7 @@ pub type Lcha = Alpha, T>; ///[HSV](struct.Hsv.html). This gives it the same ability to directly change ///the hue and colorfulness of a color, while preserving other visual aspects. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "Wp"] #[palette_component = "T"] @@ -48,7 +48,7 @@ where ///The white point associated with the color's illuminant and observer. ///D65 for 2 degree observer is used by default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub white_point: PhantomData, } @@ -444,7 +444,7 @@ mod test { raw_pixel_conversion_tests!(Lch: l, chroma, hue); raw_pixel_conversion_fail_tests!(Lch: l, chroma, hue); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Lch::new(0.3, 0.8, 0.1)).unwrap(); @@ -452,7 +452,7 @@ mod test { assert_eq!(serialized, r#"{"l":0.3,"chroma":0.8,"hue":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Lch = diff --git a/palette/src/lib.rs b/palette/src/lib.rs index 8cf3831f0..11a8ffc16 100644 --- a/palette/src/lib.rs +++ b/palette/src/lib.rs @@ -135,10 +135,16 @@ //! process reversed. //! +// Keep the standard library when running tests, too +#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] + #![doc(html_root_url = "https://docs.rs/palette/0.4.1/palette/")] #![cfg_attr(feature = "strict", deny(missing_docs))] #![cfg_attr(feature = "strict", deny(warnings))] +#[cfg(any(feature = "std", test))] +extern crate core; + #[cfg_attr(test, macro_use)] extern crate approx; @@ -150,13 +156,14 @@ extern crate num_traits; #[cfg(feature = "phf")] extern crate phf; -#[cfg(feature = "serde")] +#[cfg(feature = "serializing")] #[macro_use] extern crate serde; -#[cfg(all(test, feature = "serde"))] +#[cfg(all(test, feature = "serializing"))] extern crate serde_json; -use num_traits::{Float, NumCast, ToPrimitive, Zero}; +use num_traits::{NumCast, ToPrimitive, Zero}; +use float::Float; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; @@ -170,6 +177,7 @@ pub use palette_derive::*; pub use alpha::Alpha; pub use blend::Blend; +#[cfg(feature = "std")] pub use gradient::Gradient; pub use hsl::{Hsl, Hsla}; @@ -203,7 +211,7 @@ macro_rules! assert_ranges { unlimited {$($unlimited:ident: $unlimited_from:expr => $unlimited_to:expr),*} ) => ( { - use std::iter::repeat; + use core::iter::repeat; use Limited; { @@ -338,10 +346,12 @@ macro_rules! assert_ranges { ); } + #[macro_use] mod macros; pub mod blend; +#[cfg(feature = "std")] pub mod gradient; #[cfg(feature = "named")] @@ -367,6 +377,8 @@ mod equality; mod matrix; pub mod white_point; +pub mod float; + macro_rules! make_color { ($( #[$variant_comment:meta] @@ -867,7 +879,7 @@ impl Component for u8 { const LIMITED: bool = true; fn max_intensity() -> Self { - std::u8::MAX + core::u8::MAX } fn convert(&self) -> T { @@ -886,7 +898,7 @@ impl Component for u16 { const LIMITED: bool = true; fn max_intensity() -> Self { - std::u16::MAX + core::u16::MAX } fn convert(&self) -> T { @@ -905,7 +917,7 @@ impl Component for u32 { const LIMITED: bool = true; fn max_intensity() -> Self { - std::u32::MAX + core::u32::MAX } fn convert(&self) -> T { @@ -924,7 +936,7 @@ impl Component for u64 { const LIMITED: bool = true; fn max_intensity() -> Self { - std::u64::MAX + core::u64::MAX } fn convert(&self) -> T { diff --git a/palette/src/luma/luma.rs b/palette/src/luma/luma.rs index bef0cb8fd..bb5824ee3 100644 --- a/palette/src/luma/luma.rs +++ b/palette/src/luma/luma.rs @@ -1,10 +1,10 @@ -use std::fmt; -use std::marker::PhantomData; -use std::ops::{Add, Div, Mul, Sub}; +use core::fmt; +use core::marker::PhantomData; +use core::ops::{Add, Div, Mul, Sub}; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; use blend::PreAlpha; use clamp; @@ -28,7 +28,7 @@ pub type Lumaa = Alpha, T>; ///XYZ](struct.Xyz.html). The lack of any form of hue representation limits ///the set of operations that can be performed on it. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "S::WhitePoint"] #[palette_component = "T"] @@ -43,7 +43,7 @@ where pub luma: T, /// The kind of RGB standard. sRGB is the default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub standard: PhantomData, } @@ -611,7 +611,7 @@ where S: LumaStandard, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!(f, "{:0width$x}", self.luma, width = size) } } @@ -622,7 +622,7 @@ where S: LumaStandard, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!(f, "{:0width$X}", self.luma, width = size) } } @@ -694,7 +694,7 @@ mod test { assert_eq!(format!("{:03X}", Luma::::new(1)), "001"); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Luma::::new(0.3)).unwrap(); @@ -702,7 +702,7 @@ mod test { assert_eq!(serialized, r#"{"luma":0.3}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Luma = ::serde_json::from_str(r#"{"luma":0.3}"#).unwrap(); diff --git a/palette/src/matrix.rs b/palette/src/matrix.rs index a0ddc9681..afc7d9b29 100644 --- a/palette/src/matrix.rs +++ b/palette/src/matrix.rs @@ -1,9 +1,9 @@ //!This module provides simple matrix operations on 3x3 matrix to aid in chromatic adaptation and //!conversion calculations. -use num_traits::Float; +use float::Float; -use std::marker::PhantomData; +use core::marker::PhantomData; use {Component, Xyz}; use white_point::WhitePoint; diff --git a/palette/src/rgb/mod.rs b/palette/src/rgb/mod.rs index 384cefa72..5fe5832f9 100644 --- a/palette/src/rgb/mod.rs +++ b/palette/src/rgb/mod.rs @@ -1,7 +1,7 @@ //!RGB types, spaces and standards. -use num_traits::Float; -use std::any::Any; +use float::Float; +use core::any::Any; use {Component, Yxy}; use white_point::WhitePoint; diff --git a/palette/src/rgb/rgb.rs b/palette/src/rgb/rgb.rs index e74c6fcf4..35ca9eb3a 100644 --- a/palette/src/rgb/rgb.rs +++ b/palette/src/rgb/rgb.rs @@ -1,10 +1,10 @@ -use std::any::TypeId; -use std::fmt; -use std::marker::PhantomData; -use std::ops::{Add, Div, Mul, Sub}; +use core::any::TypeId; +use core::fmt; +use core::marker::PhantomData; +use core::ops::{Add, Div, Mul, Sub}; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use num_traits::Float; +use float::Float; use alpha::Alpha; use blend::PreAlpha; @@ -36,7 +36,7 @@ pub type Rgba = Alpha, T>; /// from a displayable RGB, such as sRGB. See the [`pixel`](pixel/index.html) /// module for encoding formats. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_rgb_space = "S::Space"] #[palette_white_point = "::WhitePoint"] @@ -57,7 +57,7 @@ pub struct Rgb { pub blue: T, /// The kind of RGB standard. sRGB is the default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub standard: PhantomData, } @@ -827,7 +827,7 @@ where S: RgbStandard, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!( f, "{:0width$x}{:0width$x}{:0width$x}", @@ -845,7 +845,7 @@ where S: RgbStandard, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let size = f.width().unwrap_or(::std::mem::size_of::() * 2); + let size = f.width().unwrap_or(::core::mem::size_of::() * 2); write!( f, "{:0width$X}{:0width$X}{:0width$X}", @@ -969,7 +969,7 @@ mod test { ); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Rgb::::new(0.3, 0.8, 0.1)).unwrap(); @@ -977,7 +977,7 @@ mod test { assert_eq!(serialized, r#"{"red":0.3,"green":0.8,"blue":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Rgb = diff --git a/palette/src/white_point.rs b/palette/src/white_point.rs index 5c61210f6..ff0c412c7 100644 --- a/palette/src/white_point.rs +++ b/palette/src/white_point.rs @@ -6,7 +6,7 @@ //! unacceptable results when attempting to color-correct a photograph taken with incandescent //! lighting. -use num_traits::Float; +use float::Float; use {cast, Component, Xyz}; diff --git a/palette/src/xyz.rs b/palette/src/xyz.rs index 6f3e0bf31..84ab59859 100644 --- a/palette/src/xyz.rs +++ b/palette/src/xyz.rs @@ -1,7 +1,7 @@ -use num_traits::Float; +use float::Float; -use std::marker::PhantomData; -use std::ops::{Add, Div, Mul, Sub}; +use core::marker::PhantomData; +use core::ops::{Add, Div, Mul, Sub}; use encoding::pixel::RawPixel; use luma::LumaStandard; @@ -26,7 +26,7 @@ pub type Xyza = Alpha, T>; ///Conversions and operations on this color space depend on the defined white /// point #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "Wp"] #[palette_component = "T"] @@ -52,7 +52,7 @@ where ///The white point associated with the color's illuminant and observer. ///D65 for 2 degree observer is used by default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub white_point: PhantomData, } @@ -565,7 +565,7 @@ mod test { raw_pixel_conversion_tests!(Xyz: x, y, z); raw_pixel_conversion_fail_tests!(Xyz: x, y, z); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Xyz::new(0.3, 0.8, 0.1)).unwrap(); @@ -573,7 +573,7 @@ mod test { assert_eq!(serialized, r#"{"x":0.3,"y":0.8,"z":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Xyz = ::serde_json::from_str(r#"{"x":0.3,"y":0.8,"z":0.1}"#).unwrap(); diff --git a/palette/src/yxy.rs b/palette/src/yxy.rs index 57eabb2a3..01f51feee 100644 --- a/palette/src/yxy.rs +++ b/palette/src/yxy.rs @@ -1,7 +1,7 @@ -use num_traits::Float; +use float::Float; -use std::marker::PhantomData; -use std::ops::{Add, Div, Mul, Sub}; +use core::marker::PhantomData; +use core::ops::{Add, Div, Mul, Sub}; use clamp; use encoding::pixel::RawPixel; @@ -22,7 +22,7 @@ pub type Yxya = Alpha, T>; /// ///Conversions and operations on this color space depend on the white point. #[derive(Debug, PartialEq, FromColor, Pixel)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))] #[palette_internal] #[palette_white_point = "Wp"] #[palette_component = "T"] @@ -48,7 +48,7 @@ where ///The white point associated with the color's illuminant and observer. ///D65 for 2 degree observer is used by default. - #[cfg_attr(feature = "serde", serde(skip))] + #[cfg_attr(feature = "serializing", serde(skip))] #[palette_unsafe_zero_sized] pub white_point: PhantomData, } @@ -528,7 +528,7 @@ mod test { raw_pixel_conversion_tests!(Yxy: x, y, luma); raw_pixel_conversion_fail_tests!(Yxy: x, y, luma); - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn serialize() { let serialized = ::serde_json::to_string(&Yxy::new(0.3, 0.8, 0.1)).unwrap(); @@ -536,7 +536,7 @@ mod test { assert_eq!(serialized, r#"{"x":0.3,"y":0.8,"luma":0.1}"#); } - #[cfg(feature = "serde")] + #[cfg(feature = "serializing")] #[test] fn deserialize() { let deserialized: Yxy = ::serde_json::from_str(r#"{"x":0.3,"y":0.8,"luma":0.1}"#).unwrap(); diff --git a/palette/tests/color_checker_data/babel.rs b/palette/tests/color_checker_data/babel.rs index b2a07ce97..de97c9865 100644 --- a/palette/tests/color_checker_data/babel.rs +++ b/palette/tests/color_checker_data/babel.rs @@ -10,6 +10,7 @@ use palette::{Xyz, Yxy, Lab, IntoColor}; use palette::white_point::D50; use super::load_data::{ColorCheckerRaw, load_babel}; +use super::MAX_ERROR; #[derive(Copy, Clone, PartialEq, Debug)] pub struct BabelData { @@ -53,9 +54,9 @@ lazy_static! { } fn check_equal(src: &BabelData, tgt: &BabelData) { - assert_relative_eq!(src.xyz, tgt.xyz, epsilon = 0.000000000001); - assert_relative_eq!(src.yxy, tgt.yxy, epsilon = 0.000000000001); - assert_relative_eq!(src.lab, tgt.lab, epsilon = 0.000000000001); + assert_relative_eq!(src.xyz, tgt.xyz, epsilon = MAX_ERROR); + assert_relative_eq!(src.yxy, tgt.yxy, epsilon = MAX_ERROR); + assert_relative_eq!(src.lab, tgt.lab, epsilon = MAX_ERROR); } pub fn run_from_yxy_tests() { diff --git a/palette/tests/color_checker_data/color_checker.rs b/palette/tests/color_checker_data/color_checker.rs index a992c9342..01cfcb6f7 100644 --- a/palette/tests/color_checker_data/color_checker.rs +++ b/palette/tests/color_checker_data/color_checker.rs @@ -10,6 +10,7 @@ use palette::{Xyz, Yxy, Lab, IntoColor}; use palette::white_point::D50; use super::load_data::{ColorCheckerRaw, load_color_checker}; +use super::MAX_ERROR; #[derive(Copy, Clone, PartialEq, Debug)] pub struct ColorCheckerData { @@ -53,9 +54,9 @@ lazy_static! { } fn check_equal(src: &ColorCheckerData, tgt: &ColorCheckerData) { - assert_relative_eq!(src.xyz, tgt.xyz, epsilon = 0.000000000001); - assert_relative_eq!(src.yxy, tgt.yxy, epsilon = 0.000000000001); - assert_relative_eq!(src.lab, tgt.lab, epsilon = 0.000000000001); + assert_relative_eq!(src.xyz, tgt.xyz, epsilon = MAX_ERROR); + assert_relative_eq!(src.yxy, tgt.yxy, epsilon = MAX_ERROR); + assert_relative_eq!(src.lab, tgt.lab, epsilon = MAX_ERROR); } pub fn run_from_yxy_tests() { diff --git a/palette/tests/color_checker_data/mod.rs b/palette/tests/color_checker_data/mod.rs index 4742e9f79..8a105662e 100644 --- a/palette/tests/color_checker_data/mod.rs +++ b/palette/tests/color_checker_data/mod.rs @@ -2,6 +2,8 @@ mod babel; mod color_checker; mod load_data; +const MAX_ERROR: f64 = 0.000000000001; + #[test] pub fn babel_from_yxy() { babel::run_from_yxy_tests(); diff --git a/palette/tests/pointer_dataset/pointer_data.rs b/palette/tests/pointer_dataset/pointer_data.rs index e54439fcc..1ed1c47ba 100644 --- a/palette/tests/pointer_dataset/pointer_data.rs +++ b/palette/tests/pointer_dataset/pointer_data.rs @@ -11,7 +11,8 @@ u', v' 0.2008907213 0.4608888395 Note: The xyz and yxy conversions do not use the updated conversion formula. So they are not used. */ -use num_traits::{Float, NumCast, ToPrimitive}; +use num_traits::{NumCast, ToPrimitive}; +use palette::float::Float; use csv; use palette::{Component, IntoColor, Lab, Lch, Xyz}; use palette::white_point::WhitePoint; @@ -92,8 +93,9 @@ fn load_data() -> Vec { } fn check_equal(src: &PointerData, tgt: &PointerData) { - assert_relative_eq!(src.lch, tgt.lch, epsilon = 0.000000000001); - assert_relative_eq!(src.lab, tgt.lab, epsilon = 0.000000000001); + const MAX_ERROR: f64 = 0.000000000001; + assert_relative_eq!(src.lch, tgt.lch, epsilon = MAX_ERROR); + assert_relative_eq!(src.lab, tgt.lab, epsilon = MAX_ERROR); } pub fn run_from_lch_tests() { diff --git a/palette_derive/src/convert/shared.rs b/palette_derive/src/convert/shared.rs index aabfd559f..eed1b7bef 100644 --- a/palette_derive/src/convert/shared.rs +++ b/palette_derive/src/convert/shared.rs @@ -82,7 +82,7 @@ pub fn add_component_where_clause(component: &Type, generics: &mut Generics, int generics .make_where_clause() .predicates - .push(parse_quote!(#component: #component_trait_path + _num_traits::Float)); + .push(parse_quote!(#component: #component_trait_path + _FloatTrait)); } pub fn add_white_point_where_clause(white_point: &Type, generics: &mut Generics, internal: bool) { diff --git a/palette_derive/src/util.rs b/palette_derive/src/util.rs index 9cab1cdef..2e10227a5 100644 --- a/palette_derive/src/util.rs +++ b/palette_derive/src/util.rs @@ -14,19 +14,19 @@ pub fn bundle_impl( if internal { quote!{ - #[allow(non_snake_case, unused_attributes, unused_qualifications)] + #[allow(non_snake_case, unused_attributes, unused_qualifications, unused_imports)] mod #const_name { - extern crate num_traits as _num_traits; + use float::Float as _FloatTrait; use super::*; #block } } } else { quote!{ - #[allow(non_snake_case, unused_attributes, unused_qualifications)] + #[allow(non_snake_case, unused_attributes, unused_qualifications, unused_imports)] mod #const_name { extern crate palette as _palette; - extern crate num_traits as _num_traits; + use self::_palette::float::Float as _FloatTrait; use super::*; #block }