tabled/grid/config/
colored_config.rs

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