nes_core 0.2.0

A NES emulator written in Rust.
Documentation
use anyhow::{Error,Result,anyhow};
use enum_dispatch::enum_dispatch;
use serde::{Deserialize, Serialize};

#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[must_use]
pub enum NesRegion {
    #[default]
    Ntsc,
    Pal,
    Dendy,
}

impl NesRegion {
    pub const fn as_slice() -> &'static [Self] {
        &[NesRegion::Ntsc, NesRegion::Pal, NesRegion::Dendy]
    }
}

impl AsRef<str> for NesRegion {
    fn as_ref(&self) -> &str {
        match self {
            Self::Ntsc => "NTSC",
            Self::Pal => "PAL",
            Self::Dendy => "Dendy",
        }
    }
}

impl TryFrom<&str> for NesRegion {
    type Error = Error;

    fn try_from(value: &str) -> Result<Self> {
        match value {
            "NTSC" => Ok(Self::Ntsc),
            "PAL" => Ok(Self::Pal),
            "Dendy" => Ok(Self::Dendy),
            _ => Err(anyhow!("invalid nes region")),
        }
    }
}

impl From<usize> for NesRegion {
    fn from(value: usize) -> Self {
        match value {
            1 => Self::Pal,
            2 => Self::Dendy,
            _ => Self::Ntsc,
        }
    }
}

#[enum_dispatch(Mapper)]
pub trait Regional {
    fn region(&self) -> NesRegion {
        NesRegion::default()
    }
    fn set_region(&mut self, _region: NesRegion) {}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[must_use]
pub enum ResetKind {
    Soft,
    Hard,
}

#[enum_dispatch(Mapper)]
pub trait Reset {
    fn reset(&mut self, _kind: ResetKind) {}
}

#[enum_dispatch(Mapper)]
pub trait Clock {
    fn clock(&mut self) -> usize {
        0
    }
    fn clock_to(&mut self, _clocks: u64) {}
}

#[macro_export]
macro_rules! btree_map {
    { $($key:expr => $value:expr),* $(,)? } => {{
        let mut m = alloc::collections::BTreeMap::new();
        $(
            m.insert($key, $value);
        )*
        m
    }};
    ($hm:ident, { $($key:expr => $value:expr),* $(,)? } ) => ({
        $(
            $hm.insert($key, $value);
        )*
    });
}