fyodor 0.4.0

Double buffered terminal renderer for Rust
Documentation
use std::ops::{Add, Div, Mul, Sub};

use crate::Dims;

use super::axis::Axis;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Pos<X, Y> {
    pub x: X,
    pub y: Y,
}

impl<X, Y> Pos<X, Y> {
    pub fn new(x: X, y: Y) -> Self {
        Self { x, y }
    }

    pub fn with_x<X2: Axis>(self, x: X2) -> Pos<X2, Y> {
        Pos::new(x, self.y)
    }

    pub fn with_y<Y2: Axis>(self, y: Y2) -> Pos<X, Y2> {
        Pos::new(self.x, y)
    }

    pub fn transmute(self) -> Pos<Y, X> {
        Pos::new(self.y, self.x)
    }

    pub fn to<X2, Y2>(self) -> Pos<X2, Y2>
    where
        X: Into<X2>,
        Y: Into<Y2>,
    {
        Pos::new(self.x.into(), self.y.into())
    }
}

impl<X> Pos<X, ()> {
    pub fn new_x(x: X) -> Pos<X, ()> {
        Pos::new(x, ())
    }
}

impl<Y> Pos<(), Y> {
    pub fn new_y(y: Y) -> Pos<(), Y> {
        Pos::new((), y)
    }
}

impl<A> Pos<A, A>
where
    A: Clone,
{
    pub fn sq(a: A) -> Self {
        Self::new(a.clone(), a)
    }
}

impl<X, Y> Pos<X, Y>
where
    X: Axis + Copy,
{
    pub fn x(&self) -> impl Axis + Copy {
        self.x
    }
}

impl<X, Y> Pos<X, Y>
where
    Y: Axis + Copy,
{
    pub fn y(&self) -> impl Axis + Copy {
        self.y
    }
}

impl<X, Y> Pos<X, Y>
where
    X: Axis,
    Y: Axis,
{
    pub fn calc_both(self, item: Pos<i32, i32>, container: Pos<i32, i32>) -> Dims {
        Dims::new(
            self.x.calc(item.x, container.x),
            self.y.calc(item.y, container.y),
        )
    }
}

impl<X, Y> From<(X, Y)> for Pos<X, Y> {
    fn from((x, y): (X, Y)) -> Self {
        Self::new(x, y)
    }
}

impl From<()> for Pos<(), ()> {
    fn from(_: ()) -> Self {
        Self::new((), ())
    }
}

impl<X, Y> Add for Pos<X, Y>
where
    X: Add,
    Y: Add,
{
    type Output = Pos<X::Output, Y::Output>;

    fn add(self, rhs: Self) -> Self::Output {
        Pos::new(self.x + rhs.x, self.y + rhs.y)
    }
}

impl<A> Add<A> for Pos<A, A>
where
    A: Add + Clone,
{
    type Output = Pos<A::Output, A::Output>;

    fn add(self, rhs: A) -> Self::Output {
        Pos::new(self.x + rhs.clone(), self.y + rhs)
    }
}

impl<X, Y> Mul for Pos<X, Y>
where
    X: Mul,
    Y: Mul,
{
    type Output = Pos<X::Output, Y::Output>;

    fn mul(self, rhs: Self) -> Self::Output {
        Pos::new(self.x * rhs.x, self.y * rhs.y)
    }
}

impl<A> Mul<A> for Pos<A, A>
where
    A: Mul + Clone,
{
    type Output = Pos<A::Output, A::Output>;

    fn mul(self, rhs: A) -> Self::Output {
        Pos::new(self.x * rhs.clone(), self.y * rhs)
    }
}

impl<X, Y> Sub for Pos<X, Y>
where
    X: Sub,
    Y: Sub,
{
    type Output = Pos<X::Output, Y::Output>;

    fn sub(self, rhs: Self) -> Self::Output {
        Pos::new(self.x - rhs.x, self.y - rhs.y)
    }
}

impl<A> Sub<A> for Pos<A, A>
where
    A: Sub + Clone,
{
    type Output = Pos<A::Output, A::Output>;

    fn sub(self, rhs: A) -> Self::Output {
        Pos::new(self.x - rhs.clone(), self.y - rhs)
    }
}

impl<X, Y> Div for Pos<X, Y>
where
    X: Div,
    Y: Div,
{
    type Output = Pos<X::Output, Y::Output>;

    fn div(self, rhs: Self) -> Self::Output {
        Pos::new(self.x / rhs.x, self.y / rhs.y)
    }
}

impl<A> Div<A> for Pos<A, A>
where
    A: Div + Clone,
{
    type Output = Pos<A::Output, A::Output>;

    fn div(self, rhs: A) -> Self::Output {
        Pos::new(self.x / rhs.clone(), self.y / rhs)
    }
}