pub mod i32 {
use abs::abs;
#[derive(Clone)]
pub struct Point(i32, i32);
#[derive(Clone)]
pub struct Rect(std::ops::Range<Point>);
impl Rect {
pub fn width(&self) -> i32 {
let x1 = self.0.start.0;
let x2 = self.0.end.0;
abs(x1, x2)
}
pub fn height(&self) -> i32 {
let y1 = self.0.start.1;
let y2 = self.0.end.1;
abs(y1, y2)
}
pub fn area(&self) -> i32 {
self.width() * self.height()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let a = Point(-2, 2);
let b = Point(-3, 5);
let r = Rect(a..b);
assert_eq!(r.width(), 1);
assert_eq!(r.height(), 3);
assert_eq!(r.area(), 3);
}
}
}
pub mod tuple {
use abs::abs;
#[derive(Clone)]
pub struct Point<T>(T, T)
where
T: Clone + PartialOrd + std::ops::Sub<Output = T>;
#[derive(Clone)]
pub struct Rect<T>(std::ops::Range<Point<T>>)
where
T: Clone + PartialOrd + std::ops::Sub<Output = T>;
impl<T> Rect<T>
where
T: Clone + PartialOrd + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>,
{
pub fn width(&self) -> T {
let x1 = self.0.clone().start.0;
let x2 = self.0.clone().end.0;
abs(x1, x2)
}
pub fn height(&self) -> T {
let y1 = self.0.clone().start.1;
let y2 = self.0.clone().end.1;
abs(y1, y2)
}
pub fn area(&self) -> T {
self.width() * self.height()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let a = Point(-2, 2);
let b = Point(-3, 5);
let r = Rect(a..b);
assert_eq!(r.width(), 1);
assert_eq!(r.height(), 3);
assert_eq!(r.area(), 3);
}
}
}
pub mod generic {
use abs::abs;
#[derive(Clone)]
pub struct Point<T>
where
T: Clone + PartialOrd + std::ops::Sub<Output = T>,
{
pub x: T,
pub y: T,
}
#[derive(Clone)]
pub struct Rect<T>
where
T: Clone + PartialOrd + std::ops::Sub<Output = T>,
{
range: std::ops::Range<Point<T>>,
}
impl<T> Rect<T>
where
T: Clone + PartialOrd + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>,
{
pub fn width(&self) -> T {
let x1 = self.range.clone().start.x;
let x2 = self.range.clone().end.x;
abs(x1, x2)
}
pub fn height(&self) -> T {
let y1 = self.range.clone().start.y;
let y2 = self.range.clone().end.y;
abs(y1, y2)
}
pub fn area(&self) -> T {
self.width() * self.height()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let a = Point { x: -2, y: 2 };
let b = Point { x: -3, y: 5 };
let r = Rect { range: a..b };
assert_eq!(r.width(), 1);
assert_eq!(r.height(), 3);
assert_eq!(r.area(), 3);
}
}
}