use crate::ffi::ffi_handle::{FFIHandle, FromFFIHandle}; use crate::ffi::{FFIResult, NonOwnedPtrString, OwnedPtrString}; use crate::static_data::{Nature, NatureLibrary, NatureLibraryImpl}; use crate::{PkmnError, Random}; use anyhow::anyhow; use std::ffi::{CStr, CString}; use std::sync::Arc; /// Creates a new nature library with a given capacity. #[no_mangle] extern "C" fn nature_library_new(capacity: usize) -> FFIHandle> { let b: Arc = Arc::new(NatureLibraryImpl::new(capacity)); FFIHandle::get_handle(b.into()) } /// Adds a new nature with name to the library. #[no_mangle] unsafe extern "C" fn nature_library_load_nature( ptr: FFIHandle>, name: NonOwnedPtrString, nature: FFIHandle>, ) -> FFIResult<()> { let nature = nature.from_ffi_handle_opt().ok_or(PkmnError::NullReference); match nature { Ok(nature) => { ptr.from_ffi_handle() .load_nature(CStr::from_ptr(name).into(), nature.clone()); FFIResult::ok(()) } Err(e) => FFIResult::err(e.into()), } } /// Gets a nature by name. #[no_mangle] unsafe extern "C" fn nature_library_get_nature( ptr: FFIHandle>, name: NonOwnedPtrString, ) -> FFIHandle> { if let Some(nature) = ptr.from_ffi_handle().get_nature(&CStr::from_ptr(name).into()) { FFIHandle::get_handle(nature.into()) } else { FFIHandle::none() } } /// Gets a random nature. #[no_mangle] unsafe extern "C" fn nature_library_get_random_nature( ptr: FFIHandle>, seed: u64, ) -> FFIResult>> { let mut rand = Random::new(seed as u128); match ptr.from_ffi_handle().get_random_nature(&mut rand) { Ok(nature) => FFIResult::ok(FFIHandle::get_handle(nature.into())), Err(e) => FFIResult::err(e), } } /// Finds a nature name by nature. #[no_mangle] unsafe extern "C" fn nature_library_get_nature_name( ptr: FFIHandle>, nature: FFIHandle>, ) -> FFIResult { match nature.from_ffi_handle_opt() { Some(nature) => { let name = ptr.from_ffi_handle().get_nature_name(&nature); match name { Ok(name) => match CString::new(name.str()) { Ok(cstr) => FFIResult::ok(cstr.into_raw()), Err(_) => FFIResult::err(anyhow!("Failed to convert nature name to C string")), }, Err(e) => FFIResult::err(e), } } None => FFIResult::err(PkmnError::NullReference.into()), } }