jismesh 0.1.1

Utilities for handling and converting JIS X0410 area mesh codes.
Documentation
use super::{JismeshError, Result};
use std::fmt;
use strum_macros::{EnumIter, EnumString};

/// 地域メッシュコードの次数
#[derive(Debug, Clone, Copy, PartialEq, EnumIter, EnumString)]
pub enum MeshLevel {
    /// 1次(80km四方)
    Lv1 = 1,
    /// 40倍(40km四方)
    X40 = 40000,
    /// 20倍(20km四方)
    X20 = 20000,
    /// 16倍(16km四方)
    X16 = 16000,
    /// 2次(10km四方)
    Lv2 = 2,
    /// 8倍(8km四方)
    X8 = 8000,
    /// 5倍(5km四方)
    X5 = 5000,
    /// 4倍(4km四方)
    X4 = 4000,
    /// 2.5倍(2.5km四方)
    X2_5 = 2500,
    /// 2倍(2km四方)
    X2 = 2000,
    /// 3次(1km四方)
    Lv3 = 3,
    /// 4次(500m四方)
    Lv4 = 4,
    /// 5次(250m四方)
    Lv5 = 5,
    /// 6次(125m四方)
    Lv6 = 6,
}

impl fmt::Display for MeshLevel {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl TryFrom<usize> for MeshLevel {
    type Error = JismeshError;

    fn try_from(value: usize) -> Result<Self> {
        match value {
            1 => Ok(MeshLevel::Lv1),
            40000 => Ok(MeshLevel::X40),
            20000 => Ok(MeshLevel::X20),
            16000 => Ok(MeshLevel::X16),
            2 => Ok(MeshLevel::Lv2),
            8000 => Ok(MeshLevel::X8),
            5000 => Ok(MeshLevel::X5),
            4000 => Ok(MeshLevel::X4),
            2500 => Ok(MeshLevel::X2_5),
            2000 => Ok(MeshLevel::X2),
            3 => Ok(MeshLevel::Lv3),
            4 => Ok(MeshLevel::Lv4),
            5 => Ok(MeshLevel::Lv5),
            6 => Ok(MeshLevel::Lv6),
            _ => Err(JismeshError::InvalidMeshLevel(value)),
        }
    }
}

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

    #[test]
    fn test_meshlevel_conversion() {
        assert_eq!(MeshLevel::try_from(1).unwrap(), MeshLevel::Lv1);
        assert_eq!(MeshLevel::try_from(6).unwrap(), MeshLevel::Lv6);

        // Test invalid conversion
        let result = MeshLevel::try_from(9999);
        assert!(result.is_err());
    }

    #[test]
    fn test_meshlevel_enum_iter() {
        let levels: Vec<MeshLevel> = MeshLevel::iter().collect();
        assert_eq!(levels.len(), 14);
        assert_eq!(levels[0], MeshLevel::Lv1);
        assert_eq!(levels[13], MeshLevel::Lv6);
    }

    #[test]
    fn test_meshlevel_string() {
        let level: MeshLevel = "Lv1".parse().unwrap();
        assert_eq!(level, MeshLevel::Lv1);
        assert_eq!(level.to_string(), "Lv1");

        let level: MeshLevel = "Lv6".parse().unwrap();
        assert_eq!(level, MeshLevel::Lv6);
        assert_eq!(level.to_string(), "Lv6");

        // Test invalid string
        let result: Result<_> = "Invalid".parse::<MeshLevel>().map_err(|e| e.into());
        assert!(result.is_err());
    }
}