#[derive(
Clone,
Copy,
Debug,
Default,
PartialEq,
serde::Serialize,
serde::Deserialize,
tui_vfx_core::ConfigSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum ShadowStyle {
#[default]
HalfBlock,
Braille {
density: f32,
},
Solid,
Gradient {
layers: u8,
},
}
impl ShadowStyle {
#[inline]
pub fn braille(density: f32) -> Self {
Self::Braille {
density: density.clamp(0.0, 1.0),
}
}
#[inline]
pub fn gradient(layers: u8) -> Self {
Self::Gradient {
layers: layers.clamp(1, 4),
}
}
pub fn name(&self) -> &'static str {
match self {
ShadowStyle::HalfBlock => "HalfBlock",
ShadowStyle::Braille { .. } => "Braille",
ShadowStyle::Solid => "Solid",
ShadowStyle::Gradient { .. } => "Gradient",
}
}
pub fn terse_description(&self) -> &'static str {
match self {
ShadowStyle::HalfBlock => "Half-block characters for soft sub-cell shadows",
ShadowStyle::Braille { .. } => "Braille patterns for dithered/density-based shadows",
ShadowStyle::Solid => "Solid color cells (space with background color)",
ShadowStyle::Gradient { .. } => "Multi-layer gradient shadow with decreasing intensity",
}
}
pub fn key_parameters(&self) -> Vec<(&'static str, String)> {
match self {
ShadowStyle::HalfBlock => vec![],
ShadowStyle::Braille { density } => vec![("density", format!("{}", density))],
ShadowStyle::Solid => vec![],
ShadowStyle::Gradient { layers } => vec![("layers", format!("{}", layers))],
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_is_half_block() {
assert_eq!(ShadowStyle::default(), ShadowStyle::HalfBlock);
}
#[test]
fn test_braille_density_clamped() {
let style = ShadowStyle::braille(2.0);
match style {
ShadowStyle::Braille { density } => assert_eq!(density, 1.0),
_ => panic!("Expected Braille variant"),
}
let style = ShadowStyle::braille(-1.0);
match style {
ShadowStyle::Braille { density } => assert_eq!(density, 0.0),
_ => panic!("Expected Braille variant"),
}
}
#[test]
fn test_gradient_layers_clamped() {
let style = ShadowStyle::gradient(10);
match style {
ShadowStyle::Gradient { layers } => assert_eq!(layers, 4),
_ => panic!("Expected Gradient variant"),
}
let style = ShadowStyle::gradient(0);
match style {
ShadowStyle::Gradient { layers } => assert_eq!(layers, 1),
_ => panic!("Expected Gradient variant"),
}
}
}