| 1 | use std::ops::{Deref, DerefMut}; |
|---|---|
| 2 | |
| 3 | use crate::grid::{ |
| 4 | ansi::ANSIBuf, |
| 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: ANSIBuf) -> &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<ANSIBuf>) -> &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<ANSIBuf>>); |
| 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 = ANSIBuf; |
| 108 | |
| 109 | fn get_color(&self, (row: usize, col: usize): (usize, usize)) -> Option<&Self::Color> { |
| 110 | self.0.as_ref().map(|map: &EntityMap |
| 111 | } |
| 112 | |
| 113 | fn is_empty(&self) -> bool { |
| 114 | self.0 |
| 115 | .as_ref() |
| 116 | .map(|cfg| cfg.is_empty() && cfg.get(Entity::Global).is_empty()) |
| 117 | .unwrap_or(default:true) |
| 118 | } |
| 119 | } |
| 120 |
