use std::fmt; use std::ops::Deref; use std::vec; use crate::cell::Cell; use crate::Label; /// A text element that has a size and can be rendered to the terminal. pub trait Element: fmt::Debug { /// Get the size of the element, in rows and columns. fn size(&self) -> Size; #[must_use] /// Render the element as lines of text that can be printed. fn render(&self) -> Vec; /// Get the number of columns occupied by this element. fn columns(&self) -> usize { self.size().cols } /// Get the number of rows occupied by this element. fn rows(&self) -> usize { self.size().rows } /// Print this element to stdout. fn print(&self) { for line in self.render() { println!("{line}"); } } #[must_use] /// Return a string representation of this element. fn display(&self) -> String { let mut out = String::new(); for line in self.render() { out.extend(line.into_iter().map(|l| l.to_string())); out.push('\n'); } out } } impl<'a> Element for Box { fn size(&self) -> Size { self.deref().size() } fn render(&self) -> Vec { self.deref().render() } fn print(&self) { self.deref().print() } } impl Element for &T { fn size(&self) -> Size { self.deref().size() } fn render(&self) -> Vec { self.deref().render() } fn print(&self) { self.deref().print() } } /// Used to specify maximum width or height. #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)] pub struct Max { pub width: Option, pub height: Option, } /// A line of text that has styling and can be displayed. #[derive(Clone, Default, Debug)] pub struct Line { items: Vec