use super::{tui_style_attrib, TuiStyle};
use crate::{throws, CommonError, CommonResult, InlineVec};
#[derive(Default, Debug, Clone)]
pub struct TuiStylesheet {
pub styles: InlineVec<TuiStyle>,
}
#[macro_export]
macro_rules! get_tui_style {
(
@from_result: $arg_stylesheet_result : expr, // Eg: from: stylesheet,
$arg_style_name : expr // Eg: "style1"
) => {
if let Ok(ref it) = $arg_stylesheet_result {
it.find_style_by_id($arg_style_name)
} else {
None
}
};
(
@from: $arg_stylesheet : expr, // Eg: from: stylesheet,
$arg_style_name : expr // Eg: "style1"
) => {
$arg_stylesheet.find_style_by_id($arg_style_name)
};
}
#[macro_export]
macro_rules! get_tui_styles {
(
@from_result: $arg_stylesheet_result : expr, // Eg: from: stylesheet,
[$($args:tt)*] // Eg: ["style1", "style2"]
) => {
if let Ok(ref it) = $arg_stylesheet_result {
it.find_styles_by_ids(&[$($args)*])
} else {
None
}
};
(
@from: $arg_stylesheet : expr, // Eg: from: stylesheet,
[$($args:tt)*] // Eg: ["style1", "style2"]
) => {
$arg_stylesheet.find_styles_by_ids(&[$($args)*])
};
}
impl TuiStylesheet {
#[must_use]
pub fn new() -> Self { Self::default() }
pub fn add_style(&mut self, style: TuiStyle) -> CommonResult<()> {
throws!({
if style.id.is_none() {
return CommonError::new_error_result_with_only_msg(
"Style id must be defined",
);
}
self.styles.push(style);
});
}
pub fn add_styles(&mut self, styles: InlineVec<TuiStyle>) -> CommonResult<()> {
throws!({
for style in styles {
self.add_style(style)?;
}
});
}
pub fn find_style_by_id(&self, arg_id: impl Into<u8>) -> Option<TuiStyle> {
let id: u8 = arg_id.into();
self.styles
.iter()
.find(|style| tui_style_attrib::Id::eq(style.id, id))
.copied()
}
#[must_use]
pub fn find_styles_by_ids(&self, ids: &[u8]) -> Option<InlineVec<TuiStyle>> {
let mut styles = InlineVec::<TuiStyle>::new();
for id in ids {
if let Some(style) = self.find_style_by_id(*id) {
styles.push(style);
}
}
if styles.is_empty() {
None
} else {
styles.into()
}
}
#[must_use]
pub fn compute(styles: &Option<InlineVec<TuiStyle>>) -> Option<TuiStyle> {
if let Some(styles) = styles {
let mut computed = TuiStyle::default();
styles.iter().for_each(|style| computed += style);
computed.into()
} else {
None
}
}
}
#[macro_export]
macro_rules! tui_stylesheet {
(
$($style:expr),*
$(,)* /* Optional trailing comma https://stackoverflow.com/a/43143459/2085356. */
) => {
{
use $crate::TryAdd;
let mut stylesheet = $crate::TuiStylesheet::new();
$(
stylesheet.try_add($style)?;
)*
stylesheet
}
};
}
pub trait TryAdd<OtherType = Self> {
fn try_add(&mut self, other: OtherType) -> CommonResult<()>;
}
impl TryAdd<TuiStyle> for TuiStylesheet {
#[allow(clippy::missing_errors_doc)]
fn try_add(&mut self, other: TuiStyle) -> CommonResult<()> { self.add_style(other) }
}
impl TryAdd<InlineVec<TuiStyle>> for TuiStylesheet {
#[allow(clippy::missing_errors_doc)]
fn try_add(&mut self, other: InlineVec<TuiStyle>) -> CommonResult<()> {
self.add_styles(other)
}
}