terminal-draw 0.1.0

A very simple library for terminal output
Documentation


pub trait Int: Sized {
    fn to_u16(&self) -> u16;
    fn from_u16(u16: u16) -> Self;
}

impl Int for u16 {
    fn to_u16(&self) -> u16 {
        *self
    }
    fn from_u16(u16: u16) -> Self {
        u16
    }
}

impl Int for u8 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as u8
    }
}
impl Int for u32 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as u32
    }
}
impl Int for u64 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as u64
    }
}
impl Int for u128 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as u128
    }
}
impl Int for usize {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as usize
    }
}

impl Int for i8 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as i8
    }
}
impl Int for i16 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as i16
    }
}
impl Int for i32 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as i32
    }
}
impl Int for i64 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as i64
    }
}
impl Int for i128 {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as i128
    }
}
impl Int for isize {
    fn to_u16(&self) -> u16 {
        *self as u16
    }
    fn from_u16(u16: u16) -> Self {
        u16 as isize
    }
}



pub trait Vec2: Sized {
    fn x(&self) -> u16;
    fn y(&self) -> u16;
    fn new(x: u16, y: u16) -> Self;

    fn from<T: Vec2>(t: &T) -> Self {
        Self::new(t.x(), t.y())
    }
    fn into<T: Vec2>(&self) -> T {
        T::from(self)
    }
}

impl<N1: Int, N2: Int> Vec2 for (N1, N2) {
    fn x(&self) -> u16 {
        self.0.to_u16()
    }
    fn y(&self) -> u16 {
        self.1.to_u16()
    }
    fn new(x: u16, y: u16) -> Self {
        (N1::from_u16(x), N2::from_u16(y))
    }
}

pub type DefVec2 = (u16, u16);

pub trait Rect: Sized {
    fn left(&self) -> u16;
    fn top(&self) -> u16;
    fn h(&self) -> u16;
    fn w(&self) -> u16;
    fn new(left: u16, top: u16, w: u16, h: u16) -> Self;

    fn bottom(&self) -> u16 {
        self.top() + self.h() - 1
    }
    fn right(&self) -> u16 {
        self.left() + self.w() - 1
    }

    fn top_left(&self) -> DefVec2 {
        (self.left(), self.top())
    }
    fn top_right(&self) -> DefVec2 {
        (self.right(), self.top())
    }
    fn bottom_left(&self) -> DefVec2 {
        (self.left(), self.bottom())
    }
    fn bottom_right(&self) -> DefVec2 {
        (self.right(), self.bottom())
    }

    fn from<T: Rect>(t: &T) -> Self {
        Self::new(t.left(), t.top(), t.w(), t.h())
    }
    fn into<T: Rect>(&self) -> T {
        T::from(self)
    }
}

impl<V1: Vec2, V2: Vec2> Rect for (V1, V2) {
    fn top(&self) -> u16 {
        self.0.y().min(self.1.y())
    }
    fn left(&self) -> u16 {
        self.0.x().min(self.1.x())
    }
    fn h(&self) -> u16 {
        self.0.y().max(self.1.y()) - self.top() + 1
    }
    fn w(&self) -> u16 {
        self.0.x().max(self.1.x()) - self.left() + 1
    }
    fn new(left: u16, top: u16, w: u16, h: u16) -> Self where Self: Sized {
        (V1::new(left, top), V2::new(left + w - 1, top + h - 1))
    }
}

pub type DefRect = (DefVec2, DefVec2);


#[cfg(test)]
mod geometry_tests {
    use super::*;

    #[test]
    fn rect_works() {
        let r1 = DefRect::new(1, 2, 1, 1);
        let r2 = DefRect::new(3, 5, 2, 2);
        
        assert_eq!(r1, ((1, 2), (1, 2)));
        assert_eq!(r2, ((3, 5), (4, 6)));
    }

    #[test]
    fn rect_size() {
        let r1 = DefRect::new(1, 2, 1, 1);

        assert_eq!(r1.w(), 1);
        assert_eq!(r1.h(), 1);
        assert_eq!(r1.bottom_right(), (1, 2));
    }
}