simple-game-utils 0.5.3

Utilities for simple games
Documentation
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
pub struct MapSize {
    pub w: u32,
    pub h: u32,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub struct MapPosition {
    pub x: u32,
    pub y: u32,
}

impl MapSize {
    #[inline]
    pub const fn new(w: u32, h: u32) -> Self {
        Self { w, h }
    }
}

impl MapPosition {
    #[inline]
    pub const fn new(x: u32, y: u32) -> Self {
        Self { x, y }
    }

    #[inline]
    pub const fn from_idx(i: usize, using: MapSize) -> MapPosition {
        MapPosition {
            x: i as u32 % using.w,
            y: i as u32 / using.w,
        }
    }
}

impl MapSize {
    #[inline]
    pub const fn count(&self) -> u32 {
        self.w * self.h
    }
}

impl MapPosition {
    #[inline]
    pub const fn to_idx(&self, using: MapSize) -> usize {
        (self.x + self.y * using.w) as usize
    }
}

macro_rules! from_num {
    ($num:ty) => {
        impl From<($num, $num)> for MapPosition {
            #[inline]
            fn from(value: ($num, $num)) -> Self {
                MapPosition {
                    x: value.0 as u32,
                    y: value.1 as u32,
                }
            }
        }
        impl From<($num, $num)> for MapSize {
            #[inline]
            fn from(value: ($num, $num)) -> Self {
                MapSize {
                    w: value.0 as u32,
                    h: value.1 as u32,
                }
            }
        }
    };
}

from_num!(u64);
from_num!(u32);
from_num!(u16);
from_num!(u8);
from_num!(usize);

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

    #[test]
    fn macros() {
        let _u64s: MapSize = (12_u64, 12_u64).into();
        let _u64p: MapPosition = (12_u64, 12_u64).into();

        assert_eq!(MapSize::new(12, 12), _u64s);
        assert_eq!(MapPosition::new(12, 12), _u64p);
    }

    #[test]
    fn indexing() {
        let size1 = MapSize::new(4, 4);
        let size2 = MapSize::new(8, 4);

        let pos1 = MapPosition::new(1, 1);

        assert_eq!(pos1.to_idx(size1), 5);
        assert_eq!(pos1.to_idx(size2), 9);
        assert_eq!(MapPosition::from_idx(15, size1), MapPosition::new(3, 3));
        assert_eq!(MapPosition::from_idx(15, size2), MapPosition::new(7, 1));
    }
}