#![cfg(feature = "std")] #![allow(dead_code, unused_macros, unused_imports)] use std::collections::HashMap; use papergrid::{ colors::NoColors, config::spanned::SpannedConfig, config::{Borders, Position}, dimension::spanned::SpannedGridDimension, dimension::{Dimension, Estimate}, grid::iterable::Grid, records::{IterRecords, Records}, }; pub fn grid(rows: usize, cols: usize) -> GridBuilder { GridBuilder::new(rows, cols) } #[derive(Debug, Default, Clone)] pub struct GridBuilder { size: (usize, usize), cfg: SpannedConfig, data: HashMap, } impl GridBuilder { pub fn new(rows: usize, cols: usize) -> Self { let mut cfg = SpannedConfig::default(); cfg.set_borders(DEFAULT_BORDERS); Self { size: (rows, cols), cfg, ..Default::default() } } pub fn config(mut self, mut f: impl FnMut(&mut SpannedConfig)) -> Self { f(&mut self.cfg); self } pub fn data( mut self, data: impl IntoIterator>>, ) -> Self { for (i, rows) in data.into_iter().enumerate() { for (j, text) in rows.into_iter().enumerate() { let text = text.into(); self.data.insert((i, j), text); } } self } pub fn change_cell(mut self, pos: Position, text: impl Into) -> Self { self.data.insert(pos, text.into()); self } pub fn build(self) -> String { let mut data = records(self.size.0, self.size.1); for ((row, col), text) in self.data { data[row][col] = text; } let grid = build_grid(data, self.cfg, self.size); grid.to_string() } } fn build_grid( data: Vec>, cfg: SpannedConfig, shape: (usize, usize), ) -> Grid>>, SpannedGridDimension, SpannedConfig, NoColors> { let records = IterRecords::new(data, shape.1, Some(shape.0)); let mut dims = SpannedGridDimension::default(); dims.estimate(&records, &cfg); Grid::new(records, dims, cfg, NoColors) } fn records(rows: usize, cols: usize) -> Vec> { let mut records = vec![vec![String::new(); cols]; rows]; (0..rows).for_each(|row| { (0..cols).for_each(|col| { let text = format!("{row}-{col}"); records[row][col] = text; }); }); records } pub const DEFAULT_BORDERS: Borders = Borders { top: Some('-'), top_left: Some('+'), top_right: Some('+'), top_intersection: Some('+'), bottom: Some('-'), bottom_left: Some('+'), bottom_right: Some('+'), bottom_intersection: Some('+'), horizontal: Some('-'), left_intersection: Some('+'), right_intersection: Some('+'), left: Some('|'), right: Some('|'), vertical: Some('|'), intersection: Some('+'), }; /// A [`Estimate`]or of a width for a [`Grid`]. /// /// [`Grid`]: crate::grid::iterable::Grid #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct ConstantDimension(pub Vec, pub Vec); impl Dimension for ConstantDimension { fn get_width(&self, column: usize) -> usize { self.0[column] } fn get_height(&self, row: usize) -> usize { self.1[row] } } impl Estimate for ConstantDimension { fn estimate(&mut self, _: R, _: &SpannedConfig) {} }