Gen7ScriptsRs/pkmn_lib_interface/src/app_interface/dynamic_data/party.rs

86 lines
2.3 KiB
Rust
Executable File

use crate::app_interface::Pokemon;
use alloc::boxed::Box;
use alloc::rc::Rc;
use core::iter::IntoIterator;
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait PartyTrait {
fn get_pokemon(&self, index: usize) -> PkmnResult<Option<Pokemon>>;
fn length(&self) -> PkmnResult<usize>;
}
pub type Party = Rc<dyn PartyTrait>;
impl<'a> IntoIterator for &'a dyn PartyTrait {
type Item = Option<Pokemon>;
type IntoIter = ExternIterator<'a, Self::Item>;
fn into_iter(self) -> Self::IntoIter {
ExternIterator::new(
self.length().unwrap(),
Box::new(move |i| self.get_pokemon(i).unwrap()),
)
}
}
#[cfg(feature = "mock_data")]
pub type MockParty = MockPartyTrait;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::PokemonImpl;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::wasm_result::WasmResult;
use crate::PkmnResult;
#[derive(Clone)]
pub struct PartyImpl {
reference: ExternRef<Self>,
}
impl PartyImpl {
pub fn new(reference: ExternRef<PartyImpl>) -> Self {
Self { reference }
}
}
impl PartyTrait for PartyImpl {
fn get_pokemon(&self, index: usize) -> PkmnResult<Option<Pokemon>> {
unsafe {
let v = party_get_pokemon(self.reference, index)
.as_res()?
.get_value();
Ok(if let Some(v) = v {
Some(Rc::new(v))
} else {
None
})
}
}
fn length(&self) -> PkmnResult<usize> {
unsafe { party_get_length(self.reference).as_res() }
}
}
impl ExternalReferenceType for PartyImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference)
}
}
extern "wasm" {
fn party_get_pokemon(
r: ExternRef<PartyImpl>,
index: usize,
) -> WasmResult<ExternRef<PokemonImpl>>;
fn party_get_length(r: ExternRef<PartyImpl>) -> WasmResult<usize>;
}
}
use crate::utils::ExternIterator;
use crate::PkmnResult;
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;