1use crate::{Error, Rgb};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum PaletteKind {
6 Static,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub struct PaletteSpec {
13 family: &'static str,
14 variant: &'static str,
15}
16
17impl PaletteSpec {
18 #[must_use]
20 pub const fn new(family: &'static str, variant: &'static str) -> Self {
21 Self { family, variant }
22 }
23
24 #[must_use]
26 pub const fn family(self) -> &'static str {
27 self.family
28 }
29
30 #[must_use]
32 pub const fn variant(self) -> &'static str {
33 self.variant
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct Palette {
40 family: &'static str,
41 variant: &'static str,
42 kind: PaletteKind,
43 colors: &'static [Rgb],
44}
45
46impl Palette {
47 #[must_use]
49 pub const fn new(
50 family: &'static str,
51 variant: &'static str,
52 kind: PaletteKind,
53 colors: &'static [Rgb],
54 ) -> Self {
55 Self {
56 family,
57 variant,
58 kind,
59 colors,
60 }
61 }
62
63 #[must_use]
65 pub const fn family(&self) -> &'static str {
66 self.family
67 }
68
69 #[must_use]
71 pub const fn variant(&self) -> &'static str {
72 self.variant
73 }
74
75 #[must_use]
77 pub const fn kind(&self) -> PaletteKind {
78 self.kind
79 }
80
81 #[must_use]
83 pub const fn spec(&self) -> PaletteSpec {
84 PaletteSpec::new(self.family, self.variant)
85 }
86
87 #[must_use]
89 pub const fn colors(&self) -> &'static [Rgb] {
90 self.colors
91 }
92
93 #[must_use]
95 pub const fn len(&self) -> usize {
96 self.colors.len()
97 }
98
99 #[must_use]
101 pub const fn is_empty(&self) -> bool {
102 self.colors.is_empty()
103 }
104
105 pub fn take(&self, n: usize) -> Result<Vec<Rgb>, Error> {
112 if n > self.colors.len() {
113 return Err(Error::TooManyColorsRequested {
114 family: self.family,
115 variant: self.variant,
116 requested: n,
117 available: self.colors.len(),
118 });
119 }
120
121 Ok(self.colors[..n].to_vec())
122 }
123
124 pub fn take_hex(&self, n: usize) -> Result<Vec<String>, Error> {
131 self.take(n)
132 .map(|colors| colors.into_iter().map(Rgb::to_hex_string).collect())
133 }
134
135 pub fn cycle(&self) -> impl Iterator<Item = Rgb> + '_ {
137 self.colors.iter().copied().cycle()
138 }
139}