tabled/settings/rotate/
mod.rs1#![cfg_attr(feature = "std", doc = "```")]
9#![cfg_attr(not(feature = "std"), doc = "```ignore")]
10use core::cmp::max;
35
36use crate::{
37 grid::records::{ExactRecords, Records, Resizable},
38 settings::TableOption,
39};
40
41#[derive(Debug)]
43pub enum Rotate {
44 Left,
48 Right,
52 Top,
58 Bottom,
64}
65
66impl<R, D, C> TableOption<R, C, D> for Rotate
67where
68 R: Records + ExactRecords + Resizable,
69{
70 fn change(self, records: &mut R, _: &mut C, _: &mut D) {
71 match self {
72 Self::Left => rotate_left(records),
73 Self::Right => rotate_right(records),
74 Self::Bottom | Self::Top => rotate_horizontal(records),
75 }
76 }
77}
78
79fn rotate_horizontal<R>(records: &mut R)
80where
81 R: Records + ExactRecords + Resizable,
82{
83 let count_rows = records.count_rows();
84 let count_cols = records.count_columns();
85
86 for row in 0..count_rows / 2 {
87 for col in 0..count_cols {
88 let last_row = count_rows - row - 1;
89 records.swap((last_row, col).into(), (row, col).into());
90 }
91 }
92}
93
94fn rotate_left<R>(records: &mut R)
95where
96 R: Records + ExactRecords + Resizable,
97{
98 let count_rows = records.count_rows();
99 let count_cols = records.count_columns();
100 let size = max(count_rows, count_cols);
101
102 {
103 for _ in count_rows..size {
104 records.push_row();
105 }
106
107 for _ in count_cols..size {
108 records.push_column();
109 }
110 }
111
112 for col in 0..size {
113 for row in col..size {
114 records.swap((col, row).into(), (row, col).into());
115 }
116 }
117
118 for row in 0..count_cols / 2 {
119 records.swap_row(row, count_cols - row - 1);
120 }
121
122 {
123 for (shift, row) in (count_rows..size).enumerate() {
124 let row = row - shift;
125 records.remove_column(row);
126 }
127
128 for (shift, col) in (count_cols..size).enumerate() {
129 let col = col - shift;
130 records.remove_row(col);
131 }
132 }
133}
134
135fn rotate_right<R>(records: &mut R)
136where
137 R: Records + ExactRecords + Resizable,
138{
139 let count_rows = records.count_rows();
140 let count_cols = records.count_columns();
141 let size = max(count_rows, count_cols);
142
143 {
144 for _ in count_rows..size {
145 records.push_row();
146 }
147
148 for _ in count_cols..size {
149 records.push_column();
150 }
151 }
152
153 for col in 0..size {
154 for row in col..size {
155 records.swap((col, row).into(), (row, col).into());
156 }
157 }
158
159 for col in 0..count_rows / 2 {
160 records.swap_column(col, count_rows - col - 1);
161 }
162
163 {
164 for (shift, row) in (count_rows..size).enumerate() {
165 let row = row - shift;
166 records.remove_column(row);
167 }
168
169 for (shift, col) in (count_cols..size).enumerate() {
170 let col = col - shift;
171 records.remove_row(col);
172 }
173 }
174}