use super::Cell;
use crate::{prelude::*, style::Styled};
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
pub struct Row<'a> {
pub(crate) cells: Vec<Cell<'a>>,
pub(crate) height: u16,
pub(crate) top_margin: u16,
pub(crate) bottom_margin: u16,
pub(crate) style: Style,
}
impl<'a> Row<'a> {
pub fn new<T>(cells: T) -> Self
where
T: IntoIterator,
T::Item: Into<Cell<'a>>,
{
Self {
cells: cells.into_iter().map(Into::into).collect(),
height: 1,
..Default::default()
}
}
#[must_use = "method moves the value of self and returns the modified value"]
pub fn cells<T>(mut self, cells: T) -> Self
where
T: IntoIterator,
T::Item: Into<Cell<'a>>,
{
self.cells = cells.into_iter().map(Into::into).collect();
self
}
#[must_use = "method moves the value of self and returns the modified value"]
pub const fn height(mut self, height: u16) -> Self {
self.height = height;
self
}
#[must_use = "method moves the value of self and returns the modified value"]
pub const fn top_margin(mut self, margin: u16) -> Self {
self.top_margin = margin;
self
}
#[must_use = "method moves the value of self and returns the modified value"]
pub const fn bottom_margin(mut self, margin: u16) -> Self {
self.bottom_margin = margin;
self
}
#[must_use = "method moves the value of self and returns the modified value"]
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
self.style = style.into();
self
}
}
impl Row<'_> {
pub(crate) const fn height_with_margin(&self) -> u16 {
self.height
.saturating_add(self.top_margin)
.saturating_add(self.bottom_margin)
}
}
impl<'a> Styled for Row<'a> {
type Item = Self;
fn style(&self) -> Style {
self.style
}
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
self.style(style)
}
}
impl<'a, Item> FromIterator<Item> for Row<'a>
where
Item: Into<Cell<'a>>,
{
fn from_iter<IterCells: IntoIterator<Item = Item>>(cells: IterCells) -> Self {
Self::new(cells)
}
}
#[cfg(test)]
mod tests {
use std::vec;
use super::*;
#[test]
fn new() {
let cells = vec![Cell::from("")];
let row = Row::new(cells.clone());
assert_eq!(row.cells, cells);
}
#[test]
fn collect() {
let cells = vec![Cell::from("")];
let row: Row = cells.iter().cloned().collect();
assert_eq!(row.cells, cells);
}
#[test]
fn cells() {
let cells = vec![Cell::from("")];
let row = Row::default().cells(cells.clone());
assert_eq!(row.cells, cells);
}
#[test]
fn height() {
let row = Row::default().height(2);
assert_eq!(row.height, 2);
}
#[test]
fn top_margin() {
let row = Row::default().top_margin(1);
assert_eq!(row.top_margin, 1);
}
#[test]
fn bottom_margin() {
let row = Row::default().bottom_margin(1);
assert_eq!(row.bottom_margin, 1);
}
#[test]
fn style() {
let style = Style::default().red().italic();
let row = Row::default().style(style);
assert_eq!(row.style, style);
}
#[test]
fn stylize() {
assert_eq!(
Row::new(vec![Cell::from("")])
.black()
.on_white()
.bold()
.not_italic()
.style,
Style::default()
.fg(Color::Black)
.bg(Color::White)
.add_modifier(Modifier::BOLD)
.remove_modifier(Modifier::ITALIC)
);
}
}