1use std::borrow::Cow;
2
3use ds_rom::rom::{Arm9AutoloadError, Rom, raw::RawBuildInfoError};
4use snafu::Snafu;
5
6use crate::config::module::ModuleKind;
7
8#[derive(Debug, Snafu)]
9pub enum RomGetCodeError {
10 #[snafu(display("Module {} not found", module_kind))]
11 ModuleNotFound { module_kind: ModuleKind },
12 #[snafu(transparent)]
13 RawBuildInfo { source: RawBuildInfoError },
14 #[snafu(transparent)]
15 Arm9Autoload { source: Arm9AutoloadError },
16}
17
18pub trait RomExt {
19 fn get_code(&self, kind: ModuleKind) -> Result<Cow<'_, [u8]>, RomGetCodeError>;
20}
21
22impl RomExt for Rom<'_> {
23 fn get_code(&self, kind: ModuleKind) -> Result<Cow<'_, [u8]>, RomGetCodeError> {
24 match kind {
25 ModuleKind::Arm9 => Ok(self.arm9().code()?.into()),
26 ModuleKind::Overlay(id) => Ok(self
27 .arm9_overlays()
28 .get(id as usize)
29 .ok_or_else(|| RomGetCodeError::ModuleNotFound { module_kind: kind })?
30 .code()
31 .into()),
32 ModuleKind::Autoload(autoload_kind) => {
33 let autoloads = self.arm9().autoloads()?;
34 let autoload = autoloads
35 .iter()
36 .find(|a| a.kind() == autoload_kind)
37 .ok_or_else(|| RomGetCodeError::ModuleNotFound { module_kind: kind })?;
38 Ok(autoload.code().to_owned().into())
39 }
40 }
41 }
42}