use std::convert::TryFrom;
use super::Point;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
Right,
Left,
Up,
Down,
}
impl Direction {
pub fn deltas(self) -> (i32, i32) {
use Direction::*;
match self {
Up => (0, 1),
Down => (0, -1),
Right => (1, 0),
Left => (-1, 0),
}
}
pub fn turn_right(self) -> Direction {
use Direction::*;
match self {
Up => Right,
Right => Down,
Down => Left,
Left => Up,
}
}
pub fn turn_left(self) -> Direction {
use Direction::*;
match self {
Up => Left,
Left => Down,
Down => Right,
Right => Up,
}
}
pub fn reverse(self) -> Direction {
use Direction::*;
match self {
Up => Down,
Left => Right,
Down => Up,
Right => Left,
}
}
pub fn iter() -> impl Iterator<Item = Direction> {
use Direction::*;
[Up, Down, Left, Right].iter().copied()
}
pub fn iter_diag() -> impl Iterator<Item = (Direction, Direction)> {
use Direction::*;
[(Up, Left), (Up, Right), (Down, Left), (Down, Right)]
.iter()
.copied()
}
}
impl Default for Direction {
fn default() -> Self {
Direction::Up
}
}
impl TryFrom<Point> for Direction {
type Error = ();
fn try_from(value: Point) -> Result<Self, Self::Error> {
match value {
Point { x: 0, y: 1 } => Ok(Direction::Up),
Point { x: 0, y: -1 } => Ok(Direction::Down),
Point { x: 1, y: 0 } => Ok(Direction::Right),
Point { x: -1, y: 0 } => Ok(Direction::Left),
_ => Err(()),
}
}
}