use std::fmt;
use crate::{cell::Cell, Color, Constraint, Element, Filled, Line, Paint, Size, Style};
#[derive(Clone, Default, Debug)]
pub struct Label(Paint<String>);
impl Label {
pub fn new(s: &str) -> Self {
Self(Paint::new(cleanup(s)))
}
pub fn blank() -> Self {
Self(Paint::default())
}
pub fn is_blank(&self) -> bool {
self.content().is_empty()
}
pub fn content(&self) -> &str {
self.0.content()
}
pub fn space() -> Self {
Self(Paint::new(" ".to_owned()))
}
pub fn boxed(self) -> Box<dyn Element> {
Box::new(self)
}
pub fn fg(self, color: Color) -> Self {
Self(self.0.fg(color))
}
pub fn bg(self, color: Color) -> Self {
Self(self.0.bg(color))
}
pub fn style(self, style: Style) -> Self {
Self(self.0.with_style(style))
}
pub fn paint(&self) -> &Paint<String> {
&self.0
}
pub fn filled(self, color: Color) -> Filled<Self> {
Filled { item: self, color }
}
pub fn to_line(self) -> Line {
Line::from(self)
}
}
impl Element for Label {
fn size(&self, _parent: Constraint) -> Size {
Size::new(self.0.width(), 1)
}
fn render(&self, _parent: Constraint) -> Vec<Line> {
vec![Line::new(self.clone())]
}
}
impl fmt::Display for Label {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Cell for Label {
type Padded = Self;
type Truncated = Self;
fn background(&self) -> Color {
self.paint().style.background
}
fn pad(&self, width: usize) -> Self::Padded {
Self(self.0.pad(width))
}
fn truncate(&self, width: usize, delim: &str) -> Self::Truncated {
Self(self.0.truncate(width, delim))
}
fn width(&self) -> usize {
Cell::width(&self.0)
}
}
impl<D: fmt::Display> From<Paint<D>> for Label {
fn from(paint: Paint<D>) -> Self {
Self(Paint {
item: cleanup(paint.item.to_string().as_str()),
style: paint.style,
})
}
}
impl From<String> for Label {
fn from(value: String) -> Self {
Self::new(value.as_str())
}
}
impl From<&str> for Label {
fn from(value: &str) -> Self {
Self::new(value)
}
}
pub fn label(s: impl Into<Paint<String>>) -> Label {
Label::from(s.into())
}
fn cleanup(input: &str) -> String {
input.chars().filter(|c| *c != '\n' && *c != '\r').collect()
}