use std::{fmt::Debug,
ops::{Add, AddAssign, Deref, DerefMut, Mul, Sub, SubAssign}};
use crate::{height, usize, ChUnit, RowHeight};
#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
pub struct RowIndex(pub ChUnit);
impl Debug for RowIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RowIndex({:?})", self.0)
}
}
pub fn row(arg_row_index: impl Into<RowIndex>) -> RowIndex { arg_row_index.into() }
mod constructor {
use super::{height, usize, ChUnit, RowHeight, RowIndex};
impl RowIndex {
pub fn new(arg_row_index: impl Into<RowIndex>) -> Self { arg_row_index.into() }
#[must_use]
pub fn as_usize(&self) -> usize { usize(self.0) }
#[must_use]
pub fn as_u16(&self) -> u16 { self.0.into() }
#[must_use]
pub fn convert_to_height(&self) -> RowHeight { height(self.0 + 1) }
}
impl From<ChUnit> for RowIndex {
fn from(ch_unit: ChUnit) -> Self { RowIndex(ch_unit) }
}
impl From<usize> for RowIndex {
fn from(val: usize) -> Self { RowIndex(val.into()) }
}
impl From<RowIndex> for usize {
fn from(row: RowIndex) -> Self { row.as_usize() }
}
impl From<u16> for RowIndex {
fn from(val: u16) -> Self { RowIndex(val.into()) }
}
impl From<i32> for RowIndex {
fn from(val: i32) -> Self { RowIndex(val.into()) }
}
}
mod ops {
use super::{Add, AddAssign, ChUnit, Deref, DerefMut, Mul, RowHeight, RowIndex, Sub,
SubAssign};
impl Deref for RowIndex {
type Target = ChUnit;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DerefMut for RowIndex {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
impl Sub<RowIndex> for RowIndex {
type Output = RowIndex;
fn sub(self, rhs: RowIndex) -> Self::Output {
let mut self_copy = self;
*self_copy -= *rhs;
self_copy
}
}
impl SubAssign<RowIndex> for RowIndex {
fn sub_assign(&mut self, rhs: RowIndex) { **self -= *rhs; }
}
impl Add<RowIndex> for RowIndex {
type Output = RowIndex;
fn add(self, rhs: RowIndex) -> Self::Output {
let mut self_copy = self;
*self_copy += *rhs;
self_copy
}
}
impl AddAssign<RowIndex> for RowIndex {
fn add_assign(&mut self, rhs: RowIndex) { *self = *self + rhs; }
}
impl Sub<RowHeight> for RowIndex {
type Output = RowIndex;
fn sub(self, rhs: RowHeight) -> Self::Output {
let mut self_copy = self;
*self_copy -= *rhs;
self_copy
}
}
impl SubAssign<RowHeight> for RowIndex {
fn sub_assign(&mut self, rhs: RowHeight) { **self -= *rhs; }
}
impl Add<RowHeight> for RowIndex {
type Output = RowIndex;
fn add(self, rhs: RowHeight) -> Self::Output {
let mut self_copy = self;
*self_copy += *rhs;
self_copy
}
}
impl AddAssign<RowHeight> for RowIndex {
fn add_assign(&mut self, rhs: RowHeight) { *self = *self + rhs; }
}
impl Mul<RowHeight> for RowIndex {
type Output = RowIndex;
fn mul(self, rhs: RowHeight) -> Self::Output {
let mut self_copy = self;
*self_copy *= *rhs;
self_copy
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ch;
#[test]
fn test_row_index_add() {
let row1 = RowIndex::from(ch(5));
let row2 = RowIndex::new(3);
let result = row1 + row2;
assert_eq!(result, RowIndex(ch(8)));
assert_eq!(*result, ch(8));
}
#[test]
fn test_row_index_sub() {
let row1 = RowIndex::from(ch(5));
let row2 = RowIndex::new(3);
let result = row1 - row2;
assert_eq!(result, RowIndex::new(2));
assert_eq!(*result, ch(2));
}
#[test]
fn test_row_index_sub_assign_add_assign() {
let mut row0 = row(5);
let row2 = row(3);
row0 -= row2;
assert_eq!(row0, row(2));
assert_eq!(*row0, ch(2));
row0 += row2;
assert_eq!(row0, row(5));
assert_eq!(*row0, ch(5));
}
#[test]
fn test_deref_and_deref_mut() {
let mut row = RowIndex::new(5);
assert_eq!(*row, ch(5));
*row = ch(10);
assert_eq!(*row, ch(10));
}
#[test]
fn test_height_mul() {
let row = RowIndex::new(5);
let height = RowHeight::new(3);
let result = row * height;
assert_eq!(result, RowIndex::new(15));
assert_eq!(*result, ch(15));
}
#[test]
fn test_height_add() {
{
let row = RowIndex::new(5);
let height = RowHeight::new(3);
let result = row + height;
assert_eq!(result, RowIndex::new(8));
assert_eq!(*result, ch(8));
}
{
let mut row = RowIndex::new(5);
let height = RowHeight::new(3);
row += height;
assert_eq!(row, RowIndex::new(8));
assert_eq!(*row, ch(8));
}
}
#[test]
fn test_height_sub() {
{
let row_idx = RowIndex::new(5);
let ht = RowHeight::new(3);
let res = row_idx - ht;
assert_eq!(res, row(2));
assert_eq!(*res, ch(2));
}
{
let mut row = RowIndex::new(5);
let height = RowHeight::new(3);
row -= height;
assert_eq!(row, RowIndex::new(2));
assert_eq!(*row, ch(2));
}
}
#[test]
fn test_as_usize() {
let row = RowIndex::new(5);
assert_eq!(row.as_usize(), 5);
}
#[test]
fn test_convert_to_height() {
let row = RowIndex::new(5);
let ht = row.convert_to_height();
assert_eq!(ht, height(6));
assert_eq!(*ht, ch(6));
}
#[test]
fn test_as_u16() {
let row = RowIndex::new(5);
assert_eq!(row.as_u16(), 5);
}
#[test]
fn test_from_usize() {
assert_eq!(RowIndex::from(5usize), row(5));
}
}