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
81
//! Palette nearest-color search, mirroring culori 4.0.2's `nearest.js`.
//!
//! ```js
//! const nearest = (colors, metric = differenceEuclidean(), accessor = d => d) => {
//! let arr = colors.map((c, idx) => ({ color: accessor(c), i: idx }));
//! return (color, n = 1, τ = Infinity) => {
//! if (isFinite(n)) {
//! n = Math.max(1, Math.min(n, arr.length - 1));
//! }
//! arr.forEach(c => { c.d = metric(color, c.color); });
//! return arr.sort((a, b) => a.d - b.d).slice(0, n).filter(c => c.d < τ).map(c => colors[c.i]);
//! };
//! };
//! ```
//!
//! The Rust translation: `nearest(palette, metric)` returns a closure
//! `Fn(&Color, usize) -> Vec<Color>` that ranks palette entries by their
//! distance under `metric` (defaulting to Euclidean in RGB) and slices off
//! the closest `n`. We use `usize::MAX` as the "Infinity" sentinel — pass
//! it to receive every sorted color.
use cratedifference_euclidean;
use crateColor;
type Metric = ;
/// Returns a closure that finds the `n` nearest colors in `palette` to a
/// query color, ordered by ascending distance under `metric`.
///
/// Pass `metric = None` to use the default Euclidean distance over `rgb`,
/// matching culori's default for `nearest(colors)`.
///
/// `n` is clamped to `palette.len() - 1` when finite, matching culori's
/// `Math.max(1, Math.min(n, arr.length - 1))`. To get every color sorted
/// by distance, pass `n = usize::MAX`. Returns an empty vector when the
/// palette is empty.
///
/// ```rust
/// use culors::{nearest, parse};
///
/// let palette: Vec<_> = ["red", "green", "blue"]
/// .iter()
/// .map(|s| parse(s).unwrap())
/// .collect();
/// let find = nearest(palette, None);
/// let target = parse("#fa0000").unwrap();
/// let hits = find(&target, 1);
/// assert_eq!(hits.len(), 1);
/// ```