Gen7ScriptsRs/pkmn_lib_interface/src/utils.rs

121 lines
3.0 KiB
Rust
Executable File

use alloc::boxed::Box;
#[macro_export]
#[cfg(feature = "mock_data")]
macro_rules! println {
($($args:tt)*) => {};
}
#[macro_export]
#[cfg(not(feature = "mock_data"))]
macro_rules! println { ($($args:tt)*) => { pkmn_lib_interface::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
#[cfg(not(feature = "mock_data"))]
#[allow(unused_macros)]
macro_rules! println_crate { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
#[cfg(not(feature = "mock_data"))]
#[allow(unused_macros)]
#[allow(unused_imports)]
pub(crate) use println_crate;
#[macro_export]
#[cfg(not(feature = "mock_data"))]
#[cfg(debug_assertions)]
macro_rules! dbg { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
#[macro_export]
#[cfg(not(debug_assertions))]
macro_rules! dbg {
($($args:tt)*) => {{}};
}
#[cfg(not(feature = "mock_data"))]
mod implementation {
use alloc::alloc::alloc;
use alloc::string::ToString;
use core::alloc::Layout;
use core::panic::PanicInfo;
use cstr_core::{c_char, CString};
extern "wasm" {
fn _print(s: *const u8);
fn _error(message: *const u8);
}
#[cfg(not(feature = "mock_data"))]
pub fn print_raw(s: &[u8]) {
unsafe {
let cstring = CString::from_vec_unchecked(s.to_vec());
_print(cstring.as_ptr());
}
}
#[panic_handler]
#[no_mangle]
#[cfg(not(feature = "mock_data"))]
#[cfg(not(test))]
pub fn begin_panic_handler(panic_info: &PanicInfo<'_>) -> ! {
let payload = panic_info.to_string();
let msg = CString::new(payload.as_bytes()).unwrap();
unsafe {
_error(msg.as_ptr());
}
loop {}
}
#[alloc_error_handler]
#[no_mangle]
#[cfg(not(feature = "mock_data"))]
#[cfg(not(test))]
fn allocation_error_handler(layout: core::alloc::Layout) -> ! {
panic!("memory allocation of {} bytes failed", layout.size())
}
#[no_mangle]
#[cfg(not(feature = "mock_data"))]
unsafe extern "wasm" fn allocate_mem(len: u32, align: u32) -> *mut u8 {
alloc(Layout::from_size_align(len as usize, align as usize).unwrap())
}
#[no_mangle]
#[cfg(not(feature = "mock_data"))]
unsafe extern "wasm" fn dealloc_cstring(ptr: *mut c_char) {
CString::from_raw(ptr);
}
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;
pub struct ExternIterator<'a, T> {
len: usize,
index: usize,
getter: Box<dyn Fn(usize) -> T + 'a>,
}
impl<'a, T> ExternIterator<'a, T> {
pub fn new(len: usize, f: Box<dyn Fn(usize) -> T + 'a>) -> Self {
Self {
len,
index: 0,
getter: f,
}
}
}
impl<'a, T> Iterator for ExternIterator<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let index = self.index;
if index >= self.len {
None
} else {
self.index += 1;
Some((self.getter)(index))
}
}
}