1 | use std::ops::{Deref, DerefMut}; |
2 | |
3 | use crate::grid::{ |
4 | color::AnsiColor, |
5 | config::{Entity, EntityMap, SpannedConfig}, |
6 | }; |
7 | |
8 | /// A spanned configuration plus colors for cells. |
9 | #[derive (Debug, Default, PartialEq, Eq, Clone)] |
10 | pub struct ColoredConfig { |
11 | config: SpannedConfig, |
12 | colors: ColorMap, |
13 | } |
14 | |
15 | impl ColoredConfig { |
16 | /// Create a new colored config. |
17 | pub fn new(config: SpannedConfig) -> Self { |
18 | Self { |
19 | config, |
20 | colors: ColorMap::default(), |
21 | } |
22 | } |
23 | |
24 | /// Set a color for a given cell. |
25 | /// |
26 | /// The outcome is the same as if you'd use [`Format`] and added a color but it'd work only with `color` feature on. |
27 | /// While this method works in all contexts. |
28 | /// |
29 | /// [`Format`]: crate::settings::Format |
30 | pub fn set_color(&mut self, pos: Entity, color: AnsiColor<'static>) -> &mut Self { |
31 | match self.colors.0.as_mut() { |
32 | Some(map) => map.insert(pos, color), |
33 | None => { |
34 | let mut colors = EntityMap::default(); |
35 | colors.insert(pos, color); |
36 | self.colors = ColorMap(Some(colors)); |
37 | } |
38 | } |
39 | |
40 | self |
41 | } |
42 | |
43 | /// Set a list of colors. |
44 | pub fn set_colors(&mut self, colors: EntityMap<AnsiColor<'static>>) -> &mut Self { |
45 | self.colors = ColorMap(Some(colors)); |
46 | self |
47 | } |
48 | |
49 | /// Remove a color for a given cell. |
50 | pub fn remove_color(&mut self, pos: Entity) -> &mut Self { |
51 | if let Some(colors) = self.colors.0.as_mut() { |
52 | colors.remove(pos); |
53 | } |
54 | |
55 | self |
56 | } |
57 | |
58 | /// Returns a list of colors. |
59 | pub fn get_colors(&self) -> &ColorMap { |
60 | &self.colors |
61 | } |
62 | |
63 | /// Returns an inner config. |
64 | pub fn into_inner(self) -> SpannedConfig { |
65 | self.config |
66 | } |
67 | } |
68 | |
69 | impl Deref for ColoredConfig { |
70 | type Target = SpannedConfig; |
71 | |
72 | fn deref(&self) -> &Self::Target { |
73 | &self.config |
74 | } |
75 | } |
76 | |
77 | impl DerefMut for ColoredConfig { |
78 | fn deref_mut(&mut self) -> &mut Self::Target { |
79 | &mut self.config |
80 | } |
81 | } |
82 | |
83 | impl From<SpannedConfig> for ColoredConfig { |
84 | fn from(value: SpannedConfig) -> Self { |
85 | Self::new(config:value) |
86 | } |
87 | } |
88 | |
89 | impl AsRef<SpannedConfig> for ColoredConfig { |
90 | fn as_ref(&self) -> &SpannedConfig { |
91 | &self.config |
92 | } |
93 | } |
94 | |
95 | /// A colors structure for [`ColoredConfig`]. |
96 | #[derive (Debug, Default, PartialEq, Eq, Clone)] |
97 | pub struct ColorMap(Option<EntityMap<AnsiColor<'static>>>); |
98 | |
99 | impl ColorMap { |
100 | /// Checks if any colors is set on. |
101 | pub fn is_empty(&self) -> bool { |
102 | self.0.is_none() |
103 | } |
104 | } |
105 | |
106 | impl crate::grid::colors::Colors for ColorMap { |
107 | type Color = AnsiColor<'static>; |
108 | |
109 | fn get_color(&self, (row: usize, col: usize): (usize, usize)) -> Option<&Self::Color> { |
110 | self.0.as_ref().map(|map: &EntityMap>| map.get(Entity::Cell(row, col))) |
111 | } |
112 | } |
113 | |