use crate::ffi::{ExternPointer, IdentifiablePointer, NativeResult, OwnedPtr}; use crate::static_data::EffectParameter; use crate::{PkmnError, StringKey}; use anyhow::anyhow; use std::ffi::{c_char, CStr, CString}; use std::ptr::drop_in_place; /// The Foreign Function Interface for abilities mod ability; /// The Foreign Function Interface for forms mod form; /// The Foreign Function Interface for growth rates mod growth_rate; /// The Foreign Function Interface for items mod item; /// The Foreign Function Interface for learnable moves mod learnable_moves; /// The Foreign Function Interface for libraries mod libraries; /// The Foreign Function Interface for moves mod move_data; /// The Foreign Function Interface for natures mod nature; /// The Foreign Function Interface for species mod species; /// The Foreign Function Interface for sets of statistics mod statistic_set; /// Instantiates an effect parameter with a boolean. #[no_mangle] extern "C" fn effect_parameter_new_bool(value: u8) -> IdentifiablePointer { Box::::new((value == 1).into()).into() } /// Instantiates an effect parameter with an integer. #[no_mangle] extern "C" fn effect_parameter_new_int(value: i64) -> IdentifiablePointer { Box::::new(value.into()).into() } /// Instantiates an effect parameter with a float. #[no_mangle] extern "C" fn effect_parameter_new_float(value: f32) -> IdentifiablePointer { Box::::new(value.into()).into() } /// Instantiates an effect parameter with a string. #[no_mangle] unsafe extern "C" fn effect_parameter_new_string( value: *const c_char, ) -> NativeResult> { let sk: StringKey = match CStr::from_ptr(value).to_str() { Ok(sk) => sk.into(), Err(_) => return NativeResult::err(PkmnError::InvalidCString.into()), }; NativeResult::ok(Box::::new(sk.into()).into()) } /// Drop an effect parameter. #[no_mangle] unsafe extern "C" fn effect_parameter_drop(ptr: OwnedPtr) { drop_in_place(ptr) } /// Get the type of an effect parameter. #[no_mangle] extern "C" fn effect_parameter_get_type(ptr: ExternPointer) -> u8 { match ptr.as_ref() { EffectParameter::Bool(_, _) => 0, EffectParameter::Int(_, _) => 1, EffectParameter::Float(_, _) => 2, EffectParameter::String(_, _) => 3, } } /// Get the boolean contained in the effect parameter, panics if the effect parameter is not a bool. #[no_mangle] extern "C" fn effect_parameter_get_as_bool(ptr: ExternPointer) -> NativeResult { let p = ptr.as_ref(); if let EffectParameter::Bool(_, b) = p { NativeResult::ok(u8::from(*b)) } else { NativeResult::err(anyhow!("Unexpected effect parameter. Expected bool, was: {}", p)) } } /// Get the int contained in the effect parameter, panics if the effect parameter is not a int. #[no_mangle] extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer) -> NativeResult { let p = ptr.as_ref(); if let EffectParameter::Int(_, b) = p { NativeResult::ok(*b) } else { NativeResult::err(anyhow!("Unexpected effect parameter. Expected int, was: {}", p)) } } /// Get the float contained in the effect parameter, panics if the effect parameter is not a float. #[no_mangle] extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer) -> NativeResult { let p = ptr.as_ref(); if let EffectParameter::Float(_, b) = p { NativeResult::ok(*b) } else { NativeResult::err(anyhow!("Unexpected effect parameter. Expected float, was: {}", p)) } } /// Get the string contained in the effect parameter, panics if the effect parameter is not a string. #[no_mangle] extern "C" fn effect_parameter_get_as_string(ptr: ExternPointer) -> NativeResult> { let p = ptr.as_ref(); if let EffectParameter::String(_, b) = p { match CString::new(b.str().to_string()) { Ok(cstr) => NativeResult::ok(cstr.into_raw()), Err(_) => NativeResult::err(PkmnError::InvalidCString.into()), } } else { NativeResult::err(anyhow!("Unexpected effect parameter. Expected string, was: {}", p)) } }