use super::*;
#[derive(Clone, Copy, Debug)]
pub enum StreamType {
Stdout,
Stderr,
}
pub trait StreamAwareFmt: Sized {
#[cfg(not(feature = "concolor"))]
#[doc(hidden)]
fn color_enabled_for(_: StreamType) -> bool {
true
}
fn fg<C: Into<Option<Color>>>(self, color: C, stream: StreamType) -> Foreground<Self> {
if Self::color_enabled_for(stream) { Foreground(self, color.into()) } else { Foreground(self, None) }
}
fn bg<C: Into<Option<Color>>>(self, color: C, stream: StreamType) -> Background<Self> {
if Self::color_enabled_for(stream) { Background(self, color.into()) } else { Background(self, None) }
}
}
impl<T: Display> StreamAwareFmt for T {}
pub trait Console: Sized {
fn fg<C: Into<Option<Color>>>(self, color: C) -> Foreground<Self>
where
Self: Display,
{
if cfg!(feature = "concolor") {
StreamAwareFmt::fg(self, color, StreamType::Stderr)
}
else {
Foreground(self, color.into())
}
}
fn bg<C: Into<Option<Color>>>(self, color: C) -> Background<Self>
where
Self: Display,
{
if cfg!(feature = "concolor") {
StreamAwareFmt::bg(self, color, StreamType::Stdout)
}
else {
Background(self, color.into())
}
}
}
impl<T: Display> Console for T {}
#[derive(Copy, Clone, Debug)]
pub struct Foreground<T>(T, Option<Color>);
impl<T: Display> Display for Foreground<T> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
if let Some(col) = self.1 { write!(f, "{}", Paint::new(&self.0).fg(col)) } else { write!(f, "{}", self.0) }
}
}
#[derive(Copy, Clone, Debug)]
pub struct Background<T>(T, Option<Color>);
impl<T: Display> Display for Background<T> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
if let Some(col) = self.1 { write!(f, "{}", Paint::new(&self.0).bg(col)) } else { write!(f, "{}", self.0) }
}
}
pub struct Palette {
state: [u16; 3],
min_brightness: f32,
}
impl Default for Palette {
fn default() -> Self {
Self::from_state([30000, 15000, 35000], 0.5)
}
}
impl Palette {
pub fn from_state(state: [u16; 3], min_brightness: f32) -> Self {
Self { state, min_brightness: min_brightness.max(0.0).min(1.0) }
}
pub fn new() -> Self {
Self::default()
}
pub fn random(&mut self) -> Color {
for i in 0..3 {
self.state[i] = (self.state[i] as usize).wrapping_add(40503 * (i * 4 + 1130)) as u16;
}
Color::Fixed(
16 + ((self.state[2] as f32 / 65535.0 * (1.0 - self.min_brightness) + self.min_brightness) * 5.0
+ (self.state[1] as f32 / 65535.0 * (1.0 - self.min_brightness) + self.min_brightness) * 30.0
+ (self.state[0] as f32 / 65535.0 * (1.0 - self.min_brightness) + self.min_brightness) * 180.0)
as u8,
)
}
}