bevy_meshem 0.4.0

A crate that offers a flexible and efficient way to generate meshes from a grid of Voxels
Documentation
use crate::prelude::{Face, Face::*};
use std::fmt;

#[derive(Clone, Copy, PartialEq)]
pub enum Direction {
    North,
    South,
    East,
    West,
    NoEast,
    NoWest,
    SoEast,
    SoWest,
}
use Direction::*;

impl Into<&'static str> for Direction {
    fn into(self) -> &'static str {
        match self {
            North => "North",
            South => "South",
            East => "East",
            West => "West",
            NoEast => "NoEast",
            NoWest => "NoWest",
            SoEast => "SoEast",
            SoWest => "SoWest",
        }
    }
}

impl fmt::Debug for Direction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Direction::{}", Into::<&'static str>::into(*self))
    }
}

impl Direction {
    pub fn add_direction(dir1: Option<Direction>, dir2: Option<Direction>) -> Option<Direction> {
        if dir1.is_none() {
            return dir2;
        }
        if dir2.is_none() {
            return dir1;
        }

        let d1 = to_cords(dir1);
        let d2 = to_cords(dir2);
        from_cords_change([d1[0] + d2[0], d1[1] + d2[1]])
    }

    pub fn opposite(&self) -> Direction {
        match self {
            North => South,
            South => North,
            East => West,
            West => East,
            SoEast => NoWest,
            NoWest => SoEast,
            SoWest => NoEast,
            NoEast => SoWest,
        }
    }

    pub fn decompose(&self) -> (Option<Direction>, Option<Direction>) {
        match self {
            North => (Some(North), None),
            South => (Some(South), None),
            East => (None, Some(East)),
            West => (None, Some(West)),
            SoEast => (Some(South), Some(East)),
            NoWest => (Some(North), Some(West)),
            SoWest => (Some(South), Some(West)),
            NoEast => (Some(North), Some(East)),
        }
    }
}

pub fn to_cords(dir: Option<Direction>) -> [i32; 2] {
    if dir.is_none() {
        return [0, 0];
    }
    let dir = dir.unwrap();
    match dir {
        North => [0, 1],
        South => [0, -1],
        East => [1, 0],
        West => [-1, 0],
        NoEast => [1, 1],
        NoWest => [-1, 1],
        SoEast => [1, -1],
        SoWest => [-1, -1],
    }
}

pub fn from_cords_change(change: [i32; 2]) -> Option<Direction> {
    if change[1] < 0 {
        if change[0] > 0 {
            return Some(Direction::SoEast);
        }
        if change[0] == 0 {
            return Some(Direction::South);
        }
        if change[0] < 0 {
            return Some(Direction::SoWest);
        }
    }
    if change[1] == 0 {
        if change[0] > 0 {
            return Some(Direction::East);
        }
        if change[0] == 0 {
            return None;
        }
        if change[0] < 0 {
            return Some(Direction::West);
        }
    }
    if change[1] > 0 {
        if change[0] > 0 {
            return Some(Direction::NoEast);
        }
        if change[0] == 0 {
            return Some(Direction::North);
        }
        if change[0] < 0 {
            return Some(Direction::NoWest);
        }
    }
    unreachable!();
}

impl From<Face> for Direction {
    fn from(value: Face) -> Self {
        match value {
            Back => Self::North,
            Forward => Self::South,
            Right => Self::East,
            Left => Self::West,
            Top => {
                assert!(false, "Face::Top cannot be cast as Direction");
                Self::North
            }
            Bottom => {
                assert!(false, "Face::Bottom cannot be cast as Direction");
                Self::South
            }
        }
    }
}

impl Into<usize> for Direction {
    fn into(self) -> usize {
        match self {
            Direction::North => 0,
            Direction::South => 1,
            Direction::East => 2,
            Direction::West => 3,
            Direction::NoEast => 4,
            Direction::NoWest => 5,
            Direction::SoEast => 6,
            Direction::SoWest => 7,
        }
    }
}

impl Into<Face> for Direction {
    fn into(self) -> Face {
        match self {
            Self::NoWest | Self::NoEast | Direction::North => Back,
            Self::SoWest | Self::SoEast | Direction::South => Forward,
            Self::West => Left,
            Self::East => Right,
        }
    }
}

impl From<u8> for Direction {
    fn from(value: u8) -> Self {
        match value {
            1 => Direction::North,
            2 => Direction::South,
            3 => Self::East,
            4 => Self::West,
            5 => Self::NoEast,
            6 => Self::NoWest,
            7 => Direction::SoEast,
            8 => Direction::SoWest,
            _ => unreachable!(),
        }
    }
}