mod catalog;
pub mod pokemon;
pub mod sound;
use serde::Serialize;
pub use catalog::GameId;
use crate::Result;
use crate::io::ByteSource;
use crate::platforms::identify;
use pokemon::{gen1, gen2, gen3, gen4, gen5, n3ds};
pub trait Game {
fn id(&self) -> GameId;
fn assets(&self) -> Result<Vec<String>>;
fn extract(&self, path: &str) -> Result<Vec<u8>>;
}
impl GameId {
pub fn is_supported(self) -> bool {
gen1::Edition::covers(self)
|| gen2::Edition::covers(self)
|| gen3::Edition::covers(self)
|| gen4::Edition::of(self).is_some()
|| gen5::Edition::of(self).is_some()
|| n3ds::Edition::of(self).is_some()
}
}
pub fn open<'a>(game: GameId, source: impl ByteSource + 'a) -> Option<Result<Box<dyn Game + 'a>>> {
if gen1::Edition::covers(game) {
release(gen1::Gen1::open(source))
} else if gen2::Edition::covers(game) {
release(gen2::Gen2::open(source))
} else if gen3::Edition::covers(game) {
gen3::Edition::of(&identify(&source).ok()?)?;
Some(gen3::Gen3::open(source).map(|game| Box::new(game) as _))
} else if gen4::Edition::of(game).is_some() {
Some(gen4::Gen4::open(source).map(|game| Box::new(game) as _))
} else if gen5::Edition::of(game).is_some() {
Some(gen5::Gen5::open(source).map(|game| Box::new(game) as _))
} else if n3ds::Edition::of(game).is_some() {
Some(n3ds::N3ds::open(source).map(|game| Box::new(game) as _))
} else {
None
}
}
fn release<'a>(opened: Result<impl Game + 'a>) -> Option<Result<Box<dyn Game + 'a>>> {
match opened {
Err(crate::Error::Unsupported(_)) => None,
opened => Some(opened.map(|game| Box::new(game) as _)),
}
}
pub(crate) fn json(value: &(impl Serialize + ?Sized)) -> Result<Vec<u8>> {
Ok(serde_json::to_vec_pretty(value)?)
}