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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
use std::fmt::{self, Debug, Display};
mod colour;
mod modifier;
pub use colour::Colour;
pub use modifier::Modifier;
/// We use `ColChar` to say exactly what each pixel should look like and what colour it should be. That is, the [`View`](super::super::View)'s canvas is just a vector of `ColChar`s under the hood. `ColChar` has the [`text_char`](ColChar::text_char) and [`modifier`](ColChar::modifier) properties. [`text_char`](ColChar::text_char) is the single ascii character used as the "pixel" when the [`View`](super::super::View) is rendered, whereas [`modifier`](ColChar::modifier) can give that pixel a colour or make it bold/italic
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ColChar {
/// The actual character that will dictate the appearance of the pixel
pub text_char: char,
/// The modifier that will be applied to the text character
pub modifier: Modifier,
}
impl ColChar {
/// A solid █ character with no [`Modifier`].
///
/// Using a sequence like this will create a red █ `ColChar`
/// ```rs
/// ColChar::SOLID.with_rgb(255,0,0)
/// ```
pub const SOLID: Self = Self {
text_char: '█',
modifier: Modifier::None,
};
/// A less solid ░ character with no [`Modifier`]
pub const BACKGROUND: Self = Self {
text_char: '░',
modifier: Modifier::None,
};
/// A whitespace character with no [`Modifier`]
pub const EMPTY: Self = Self {
text_char: ' ',
modifier: Modifier::None,
};
/// For use with the [`Sprite`](crate::elements::Sprite) and [`Text`](crate::elements::Text) elements, which consider a regular whitespace a transparent character
pub const VOID: Self = Self {
text_char: '\u{2008}',
modifier: Modifier::None,
};
/// Create a new `ColChar` with a text character and a [`Modifier`]
#[must_use]
pub const fn new(text_char: char, modifier: Modifier) -> Self {
Self {
text_char,
modifier,
}
}
/// Return a `ColChar` with the same `modifier` and new `text_char`
#[must_use]
pub const fn with_char(self, text_char: char) -> Self {
Self {
text_char,
modifier: self.modifier,
}
}
/// Return a `ColChar` with the same `text_char` and new `modifier`
#[must_use]
pub const fn with_mod(self, modifier: Modifier) -> Self {
Self {
text_char: self.text_char,
modifier,
}
}
/// Return a `ColChar` with the same `text_char` and new `modifier` of the `Modifier::Colour` enum variant from RGB values
#[must_use]
pub const fn with_rgb(self, r: u8, g: u8, b: u8) -> Self {
Self {
text_char: self.text_char,
modifier: Modifier::from_rgb(r, g, b),
}
}
/// Return a `ColChar` with the same `text_char` and new `modifier` of the `Modifier::Colour` enum variant from HSV values
#[must_use]
pub fn with_hsv(self, h: u8, s: u8, v: u8) -> Self {
Self {
text_char: self.text_char,
modifier: Modifier::from_hsv(h, s, v),
}
}
/// Return a `ColChar` with the same `text_char` and new `modifier` of the `Modifier::Colour` enum variant from an HSV value
#[must_use]
pub const fn with_colour(self, colour: Colour) -> Self {
Self {
text_char: self.text_char,
modifier: Modifier::Colour(colour),
}
}
/// Return the displayed `ColChar`, omitting the `Modifier`s where necessary
pub(crate) fn display_with_prev_and_next(
self,
f: &mut fmt::Formatter,
prev_mod: Option<Modifier>,
next_mod: Option<Modifier>,
) -> fmt::Result {
let modifier = if prev_mod == Some(self.modifier) {
Modifier::None
} else {
self.modifier
};
let end = if next_mod == Some(self.modifier) {
Modifier::None
} else {
Modifier::END
};
write!(f, "{}{}{}", modifier, self.text_char, end)
}
}
impl Default for ColChar {
fn default() -> Self {
Self::SOLID
}
}
impl Display for ColChar {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.modifier {
Modifier::None => write!(f, "{}", self.text_char),
_ => write!(f, "{}{}{}", self.modifier, self.text_char, Modifier::END),
}
}
}