1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! Legacy hex serializers `format_hex` and `format_hex8`.
//!
//! Mirrors culori 4.0.2's `formatHex` / `formatHex8`
//! (`node_modules/culori/src/formatter.js`):
//!
//! ```js
//! const clamp = value => Math.max(0, Math.min(1, value || 0));
//! const fixup = value => Math.round(clamp(value) * 255);
//! ```
//!
//! Steps culori's pipeline takes:
//! 1. Convert input to `rgb` (sRGB).
//! 2. Per channel: replace NaN/undefined with 0 (`value || 0`), clamp to
//! [0, 1], multiply by 255, round half-away-from-zero.
//! 3. Pack into `#rrggbb` (or `#rrggbbaa`) lowercase hex.
//!
//! For `format_hex8`, an absent alpha is treated as 1 (matching culori's
//! `color.alpha !== undefined ? color.alpha : 1`).
use crateColor;
use crateRgb;
/// Map an f64 channel to its 0..=255 byte using culori's `fixup` rule:
/// NaN → 0, clamp to [0, 1], `Math.round(x * 255)`.
///
/// Rust's `f64::round()` rounds half away from zero, which matches JS
/// `Math.round` for non-negative inputs (and the input is always >= 0
/// here because we clamp first).
pub
pub
/// Serialize a color as a legacy `#rrggbb` hex string.
///
/// Input is converted to sRGB; channels are clamped to 0..=255 with rounding
/// (NaN → 0). Alpha is ignored. Output is lowercase.
///
/// ```rust
/// use culors::{format_hex, parse};
/// let red = parse("tomato").unwrap();
/// assert_eq!(format_hex(&red), "#ff6347");
/// ```
/// Serialize a color as a legacy `#rrggbbaa` hex string.
///
/// Input is converted to sRGB; channels and alpha are clamped to 0..=255 with
/// rounding (NaN → 0). Absent alpha is treated as 1, yielding `…ff`.
///
/// ```rust
/// use culors::{format_hex8, parse};
/// let red = parse("rgb(255 255 255 / 0.5)").unwrap();
/// assert_eq!(format_hex8(&red), "#ffffff80");
/// ```