use crate::ffi::ffi_handle::{FFIHandle, FFIObject, FromFFIHandle}; use crate::ffi::{FFIResult, OwnedPtrString}; use crate::static_data::EffectParameter; use crate::{PkmnError, StringKey}; use anyhow::anyhow; use std::ffi::{c_char, CStr, CString}; use std::ops::Deref; use std::sync::Arc; /// 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) -> FFIHandle> { FFIHandle::get_handle(FFIObject::EffectParameter(Arc::new(EffectParameter::from(value == 1)))) } /// Instantiates an effect parameter with an integer. #[no_mangle] extern "C" fn effect_parameter_new_int(value: i64) -> FFIHandle> { FFIHandle::get_handle(FFIObject::EffectParameter(Arc::new(EffectParameter::from(value)))) } /// Instantiates an effect parameter with a float. #[no_mangle] extern "C" fn effect_parameter_new_float(value: f32) -> FFIHandle> { FFIHandle::get_handle(FFIObject::EffectParameter(Arc::new(EffectParameter::from(value)))) } /// Instantiates an effect parameter with a string. #[no_mangle] unsafe extern "C" fn effect_parameter_new_string(value: *const c_char) -> FFIResult>> { let sk: StringKey = match CStr::from_ptr(value).to_str() { Ok(sk) => sk.into(), Err(_) => return FFIResult::err(PkmnError::InvalidCString.into()), }; FFIResult::ok(FFIHandle::get_handle(FFIObject::EffectParameter(Arc::new( EffectParameter::from(sk), )))) } /// Get the type of an effect parameter. #[no_mangle] extern "C" fn effect_parameter_get_type(ptr: FFIHandle>) -> u8 { match ptr.from_ffi_handle().deref() { 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: FFIHandle>) -> FFIResult { let p = ptr.from_ffi_handle(); if let EffectParameter::Bool(b) = p.deref() { FFIResult::ok(u8::from(*b)) } else { FFIResult::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: FFIHandle>) -> FFIResult { let p = ptr.from_ffi_handle(); if let EffectParameter::Int(b) = p.deref() { FFIResult::ok(*b) } else { FFIResult::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: FFIHandle>) -> FFIResult { let p = ptr.from_ffi_handle(); if let EffectParameter::Float(b) = p.deref() { FFIResult::ok(*b) } else { FFIResult::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: FFIHandle>) -> FFIResult { let p = ptr.from_ffi_handle(); if let EffectParameter::String(b) = p.deref() { match CString::new(b.str().to_string()) { Ok(cstr) => FFIResult::ok(OwnedPtrString(cstr.into_raw())), Err(_) => FFIResult::err(PkmnError::InvalidCString.into()), } } else { FFIResult::err(anyhow!("Unexpected effect parameter. Expected string, was: {}", p)) } }