blob: 4264171909566098f0e9a156ecc1bcad5f0d39d1 [file] [log] [blame]
//! This module contains a [`Rotate`] primitive which can be used in order to rotate [`Table`].
//!
//! It's also possible to transpose the table at the point of construction.
//! See [`Builder::index`].
//!
//! # Example
//!
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! use tabled::{Table, settings::Rotate};
//!
//! let data = [[1, 2, 3], [4, 5, 6]];
//!
//! let table = Table::new(data).with(Rotate::Left).to_string();
//!
//! assert_eq!(
//! table,
//! concat!(
//! "+---+---+---+\n",
//! "| 2 | 3 | 6 |\n",
//! "+---+---+---+\n",
//! "| 1 | 2 | 5 |\n",
//! "+---+---+---+\n",
//! "| 0 | 1 | 4 |\n",
//! "+---+---+---+",
//! )
//! );
//! ```
//!
//! [`Table`]: crate::Table
//! [`Builder::index`]: crate::builder::Builder::index
// use core::cmp::max;
use core::cmp::max;
use crate::{
grid::records::{ExactRecords, Records, Resizable},
settings::TableOption,
};
/// Rotate can be used to rotate a table by 90 degrees.
#[derive(Debug)]
pub enum Rotate {
/// Rotate [`Table`] to the left.
///
/// [`Table`]: crate::Table
Left,
/// Rotate [`Table`] to the right.
///
/// [`Table`]: crate::Table
Right,
/// Rotate [`Table`] to the top.
///
/// So the top becomes the bottom.
///
/// [`Table`]: crate::Table
Top,
/// Rotate [`Table`] to the bottom.
///
/// So the top becomes the bottom.
///
/// [`Table`]: crate::Table
Bottom,
}
impl<R, D, C> TableOption<R, D, C> for Rotate
where
R: Records + ExactRecords + Resizable,
{
fn change(self, records: &mut R, _: &mut C, _: &mut D) {
let count_rows = records.count_rows();
let count_cols = records.count_columns();
match self {
Self::Left => {
let size = max(count_rows, count_cols);
{
for _ in count_rows..size {
records.push_row();
}
for _ in count_cols..size {
records.push_column();
}
}
for col in 0..size {
for row in col..size {
records.swap((col, row), (row, col));
}
}
for row in 0..count_cols / 2 {
records.swap_row(row, count_cols - row - 1);
}
{
for (shift, row) in (count_rows..size).enumerate() {
let row = row - shift;
records.remove_column(row);
}
for (shift, col) in (count_cols..size).enumerate() {
let col = col - shift;
records.remove_row(col);
}
}
}
Self::Right => {
let size = max(count_rows, count_cols);
{
for _ in count_rows..size {
records.push_row();
}
for _ in count_cols..size {
records.push_column();
}
}
for col in 0..size {
for row in col..size {
records.swap((col, row), (row, col));
}
}
for col in 0..count_rows / 2 {
records.swap_column(col, count_rows - col - 1);
}
{
for (shift, row) in (count_rows..size).enumerate() {
let row = row - shift;
records.remove_column(row);
}
for (shift, col) in (count_cols..size).enumerate() {
let col = col - shift;
records.remove_row(col);
}
}
}
Self::Bottom | Self::Top => {
for row in 0..count_rows / 2 {
for col in 0..count_cols {
let last_row = count_rows - row - 1;
records.swap((last_row, col), (row, col));
}
}
}
}
}
}