chromashift/
lib.rs

1#![deny(warnings)]
2
3use core::fmt;
4mod a98_rgb;
5mod conversion;
6mod distance;
7mod hex;
8mod hsb;
9mod hsl;
10mod hwb;
11mod lab;
12mod lch;
13mod linear_rgb;
14mod mix;
15mod named;
16mod oklab;
17mod oklch;
18mod srgb;
19#[cfg(test)]
20mod tests;
21mod wcag;
22mod xyzd50;
23mod xyzd65;
24
25pub use a98_rgb::A98Rgb;
26pub use distance::ColorDistance;
27pub use hex::Hex;
28pub use hsb::Hsv;
29pub use hsl::Hsl;
30pub use hwb::Hwb;
31pub use lab::Lab;
32pub use lch::Lch;
33pub use linear_rgb::LinearRgb;
34pub use mix::{ColorMix, ColorMixPolar, HueInterpolation};
35pub use named::Named;
36pub use oklab::Oklab;
37pub use oklch::Oklch;
38pub use srgb::Srgb;
39pub use wcag::{WcagColorContrast, WcagLevel};
40pub use xyzd50::XyzD50;
41pub use xyzd65::XyzD65;
42
43#[derive(Debug, Clone, Copy, PartialEq)]
44pub enum Color {
45	A98Rgb(A98Rgb),
46	Hsv(Hsv),
47	Hsl(Hsl),
48	Hex(Hex),
49	Hwb(Hwb),
50	Lab(Lab),
51	Lch(Lch),
52	LinearRgb(LinearRgb),
53	Named(Named),
54	Oklab(Oklab),
55	Oklch(Oklch),
56	Srgb(Srgb),
57	XyzD50(XyzD50),
58	XyzD65(XyzD65),
59}
60
61impl fmt::Display for Color {
62	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63		match self {
64			Self::A98Rgb(a) => fmt::Display::fmt(a, f),
65			Self::Hex(h) => fmt::Display::fmt(h, f),
66			Self::Hsv(h) => fmt::Display::fmt(h, f),
67			Self::Hsl(h) => fmt::Display::fmt(h, f),
68			Self::Hwb(h) => fmt::Display::fmt(h, f),
69			Self::Lab(l) => fmt::Display::fmt(l, f),
70			Self::Lch(l) => fmt::Display::fmt(l, f),
71			Self::LinearRgb(l) => fmt::Display::fmt(l, f),
72			Self::Named(n) => fmt::Display::fmt(n, f),
73			Self::Oklab(o) => fmt::Display::fmt(o, f),
74			Self::Oklch(o) => fmt::Display::fmt(o, f),
75			Self::Srgb(s) => fmt::Display::fmt(s, f),
76			Self::XyzD50(x) => fmt::Display::fmt(x, f),
77			Self::XyzD65(x) => fmt::Display::fmt(x, f),
78		}
79	}
80}
81
82impl From<Color> for XyzD65 {
83	fn from(value: Color) -> Self {
84		match value {
85			Color::A98Rgb(a) => a.into(),
86			Color::Hex(h) => h.into(),
87			Color::Hsv(h) => h.into(),
88			Color::Hsl(h) => h.into(),
89			Color::Hwb(h) => h.into(),
90			Color::Lab(l) => l.into(),
91			Color::Lch(l) => l.into(),
92			Color::LinearRgb(l) => l.into(),
93			Color::Named(n) => n.into(),
94			Color::Oklab(o) => o.into(),
95			Color::Oklch(o) => o.into(),
96			Color::Srgb(s) => s.into(),
97			Color::XyzD50(x) => x.into(),
98			Color::XyzD65(x) => x,
99		}
100	}
101}
102
103pub const COLOR_EPSILON: f64 = 0.0072;
104
105pub(crate) fn round_dp(f: f64, d: u32) -> f64 {
106	let factor = 10u32.pow(d) as f64;
107	(f * factor).round() / factor
108}