use std::{fmt::Debug,
ops::{Add, Deref, DerefMut, Div, Sub, SubAssign}};
use crate::{ch, row, ChUnit, RowIndex};
#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
pub struct RowHeight(pub ChUnit);
impl Debug for RowHeight {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RowHeight({:?})", self.0)
}
}
pub fn height(arg_row_height: impl Into<RowHeight>) -> RowHeight { arg_row_height.into() }
mod constructor {
use super::{ch, row, ChUnit, RowHeight, RowIndex};
impl RowHeight {
pub fn new(arg_row_height: impl Into<RowHeight>) -> Self { arg_row_height.into() }
#[must_use]
pub fn convert_to_row_index(&self) -> RowIndex { row(self.0 - ch(1)) }
}
impl From<ChUnit> for RowHeight {
fn from(ch_unit: ChUnit) -> Self { RowHeight(ch_unit) }
}
impl From<usize> for RowHeight {
fn from(height: usize) -> Self { RowHeight(ch(height)) }
}
impl From<u16> for RowHeight {
fn from(val: u16) -> Self { RowHeight(val.into()) }
}
impl From<i32> for RowHeight {
fn from(val: i32) -> Self { RowHeight(val.into()) }
}
impl From<u8> for RowHeight {
fn from(val: u8) -> Self { RowHeight(val.into()) }
}
}
mod ops {
use super::{height, Add, ChUnit, Deref, DerefMut, Div, RowHeight, Sub, SubAssign};
impl Deref for RowHeight {
type Target = ChUnit;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DerefMut for RowHeight {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
impl Add<RowHeight> for RowHeight {
type Output = RowHeight;
fn add(self, rhs: RowHeight) -> Self::Output {
let mut self_copy = self;
*self_copy += *rhs;
self_copy
}
}
impl Sub<RowHeight> for RowHeight {
type Output = RowHeight;
fn sub(self, rhs: RowHeight) -> Self::Output {
let mut self_copy = self;
*self_copy -= *rhs;
self_copy
}
}
impl SubAssign<RowHeight> for RowHeight {
fn sub_assign(&mut self, rhs: RowHeight) { **self -= *rhs; }
}
impl Div<ChUnit> for RowHeight {
type Output = RowHeight;
fn div(self, rhs: ChUnit) -> Self::Output {
let value = *self / rhs;
height(value)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_height_new() {
let height = RowHeight::new(10);
assert_eq!(height, RowHeight(10.into()));
assert_eq!(*height, ch(10));
}
#[test]
fn test_height_add() {
let height1 = RowHeight(10.into());
let height2 = RowHeight(4.into());
let result = height1 + height2;
assert_eq!(result, RowHeight(14.into()));
assert_eq!(*result, ch(14));
}
#[test]
fn test_height_sub() {
{
let height1 = height(10);
let height2 = height(4);
let result = height1 - height2;
assert_eq!(result, height(6));
assert_eq!(*result, ch(6));
}
{
let mut height1 = height(10);
let height2 = height(4);
height1 -= height2;
assert_eq!(height1, height(6));
assert_eq!(*height1, ch(6));
}
}
#[test]
fn test_deref_and_deref_mut() {
let mut height = RowHeight(10.into());
assert_eq!(*height, ch(10));
*height = ch(20);
assert_eq!(*height, ch(20));
}
#[test]
fn test_div_ch_unit() {
assert_eq!(height(10) / ch(2), height(5));
}
#[test]
fn test_convert_to_row_index() {
assert_eq!(height(10).convert_to_row_index(), row(9));
}
#[test]
fn test_convert_from_usize() {
assert_eq!(RowHeight::from(10usize), height(10));
}
}