use std::num::{
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
};
use std::ptr::NonNull;
#[derive(Debug)]
pub struct ScriptModuleCallHandle {
pub(crate) internal: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
}
#[derive(thiserror::Error, Debug)]
pub enum ScriptModuleCallHandleError {
#[error("key contains null byte")]
KeyContainsNullByte(std::ffi::NulError),
#[error("value contains null byte")]
ValueContainsNullByte(std::ffi::NulError),
#[error("too many elements")]
TooManyElements,
}
pub type ScriptModuleCallHandleResult<T> = std::result::Result<T, ScriptModuleCallHandleError>;
impl ScriptModuleCallHandle {
pub unsafe fn from_raw(
ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
) -> ScriptModuleCallHandle {
ScriptModuleCallHandle { internal: ptr }
}
pub fn len(&self) -> usize {
unsafe { ((*self.internal).get_param_num)() as usize }
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get_param<'a, T: FromScriptModuleParam<'a>>(&'a self, index: usize) -> Option<T> {
T::from_param(self, index)
}
pub fn get_param_int(&self, index: usize) -> i32 {
unsafe { ((*self.internal).get_param_int)(index as i32) }
}
pub fn get_param_float(&self, index: usize) -> f64 {
unsafe { ((*self.internal).get_param_double)(index as i32) }
}
pub fn get_param_str(&self, index: usize) -> Option<String> {
unsafe {
let c_str = ((*self.internal).get_param_string)(index as i32);
if c_str.is_null() {
None
} else {
Some(
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned(),
)
}
}
}
pub fn get_param_data<T>(&self, index: usize) -> Option<NonNull<T>> {
unsafe {
let data_ptr = ((*self.internal).get_param_data)(index as i32);
NonNull::new(data_ptr as *mut T)
}
}
pub fn get_param_boolean(&self, index: usize) -> bool {
unsafe { ((*self.internal).get_param_boolean)(index as i32) }
}
pub fn get_param_table_int(
&self,
index: usize,
key: &str,
) -> ScriptModuleCallHandleResult<i32> {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
Ok(unsafe { ((*self.internal).get_param_table_int)(index as i32, c_key.as_ptr()) })
}
pub fn get_param_table_float(
&self,
index: usize,
key: &str,
) -> ScriptModuleCallHandleResult<f64> {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
Ok(unsafe { ((*self.internal).get_param_table_double)(index as i32, c_key.as_ptr()) })
}
pub fn get_param_table_str(
&self,
index: usize,
key: &str,
) -> ScriptModuleCallHandleResult<Option<String>> {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
unsafe {
let c_str = ((*self.internal).get_param_table_string)(index as i32, c_key.as_ptr());
Ok(if c_str.is_null() {
None
} else {
Some(
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned(),
)
})
}
}
pub fn get_param_array_len(&self, index: usize) -> usize {
unsafe { ((*self.internal).get_param_array_num)(index as i32) as usize }
}
pub fn get_param_array_int(&self, index: usize, array_index: usize) -> i32 {
unsafe { ((*self.internal).get_param_array_int)(index as i32, array_index as i32) }
}
pub fn get_param_array_float(&self, index: usize, array_index: usize) -> f64 {
unsafe { ((*self.internal).get_param_array_double)(index as i32, array_index as i32) }
}
pub fn get_param_array_str(&self, index: usize, array_index: usize) -> Option<String> {
unsafe {
let c_str = ((*self.internal).get_param_array_string)(index as i32, array_index as i32);
if c_str.is_null() {
None
} else {
Some(
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned(),
)
}
}
}
pub fn set_error(&mut self, message: &str) -> ScriptModuleCallHandleResult<()> {
let c_message = std::ffi::CString::new(message)
.map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
unsafe {
((*self.internal).set_error)(c_message.as_ptr());
}
Ok(())
}
pub fn push_result<T: IntoScriptModuleReturnValue>(
&mut self,
value: T,
) -> Result<(), IntoScriptModuleReturnValueError<T::Err>> {
value.push_into(self)
}
pub fn push_result_int(&mut self, value: i32) {
unsafe {
((*self.internal).push_result_int)(value);
}
}
pub fn push_result_float(&mut self, value: f64) {
unsafe {
((*self.internal).push_result_double)(value);
}
}
pub fn push_result_str(&mut self, value: &str) -> ScriptModuleCallHandleResult<()> {
let c_value = std::ffi::CString::new(value)
.map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
unsafe {
((*self.internal).push_result_string)(c_value.as_ptr());
}
Ok(())
}
pub fn push_result_data<T>(&mut self, value: *const T) {
unsafe {
((*self.internal).push_result_data)(value as *const std::ffi::c_void);
}
}
pub fn push_result_table_int<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
where
T: std::iter::IntoIterator<Item = (&'a str, i32)>,
{
let mut keys = Vec::new();
let mut values = Vec::new();
for (key, value) in table {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
keys.push(c_key);
values.push(value);
}
let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
unsafe {
((*self.internal).push_result_table_int)(
key_ptrs.as_ptr(),
values.as_ptr(),
key_ptrs.len() as i32,
);
}
Ok(())
}
pub fn push_result_table_float<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
where
T: std::iter::IntoIterator<Item = (&'a str, f64)>,
{
let mut keys = Vec::new();
let mut values = Vec::new();
for (key, value) in table {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
keys.push(c_key);
values.push(value);
}
let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
unsafe {
((*self.internal).push_result_table_double)(
key_ptrs.as_ptr(),
values.as_ptr(),
key_ptrs.len() as i32,
);
}
Ok(())
}
pub fn push_result_table_str<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
where
T: std::iter::IntoIterator<Item = (&'a str, &'a str)>,
{
let mut keys = Vec::new();
let mut values = Vec::new();
for (key, value) in table {
let c_key = std::ffi::CString::new(key)
.map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
let c_value = std::ffi::CString::new(value)
.map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
keys.push(c_key);
values.push(c_value);
}
if keys.len() > i32::MAX as usize {
return Err(ScriptModuleCallHandleError::TooManyElements);
}
let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
let value_ptrs: Vec<*const std::os::raw::c_char> =
values.iter().map(|v| v.as_ptr()).collect();
unsafe {
((*self.internal).push_result_table_string)(
key_ptrs.as_ptr(),
value_ptrs.as_ptr(),
key_ptrs.len() as i32,
);
}
Ok(())
}
pub fn push_result_array_int(&mut self, values: &[i32]) -> ScriptModuleCallHandleResult<()> {
if values.len() > i32::MAX as usize {
return Err(ScriptModuleCallHandleError::TooManyElements);
}
unsafe {
((*self.internal).push_result_array_int)(values.as_ptr(), values.len() as i32);
}
Ok(())
}
pub fn push_result_array_float(&mut self, values: &[f64]) -> ScriptModuleCallHandleResult<()> {
if values.len() > i32::MAX as usize {
return Err(ScriptModuleCallHandleError::TooManyElements);
}
unsafe {
((*self.internal).push_result_array_double)(values.as_ptr(), values.len() as i32);
}
Ok(())
}
pub fn push_result_array_str(&mut self, values: &[&str]) -> ScriptModuleCallHandleResult<()> {
let c_values: Vec<std::ffi::CString> = values
.iter()
.map(|s| std::ffi::CString::new(*s))
.collect::<Result<_, _>>()
.map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
if c_values.len() > i32::MAX as usize {
return Err(ScriptModuleCallHandleError::TooManyElements);
}
let c_value_ptrs: Vec<*const std::os::raw::c_char> =
c_values.iter().map(|s| s.as_ptr()).collect();
unsafe {
((*self.internal).push_result_array_string)(
c_value_ptrs.as_ptr(),
c_value_ptrs.len() as i32,
);
}
Ok(())
}
pub fn push_result_boolean(&mut self, value: bool) {
unsafe {
((*self.internal).push_result_boolean)(value);
}
}
}
impl From<*mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM> for ScriptModuleCallHandle {
fn from(ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM) -> Self {
Self { internal: ptr }
}
}
pub trait FromScriptModuleParam<'a>: Sized {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self>;
}
pub use aviutl2_macros::FromScriptModuleParam;
impl<'a> FromScriptModuleParam<'a> for i32 {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(param.get_param_int(index))
} else {
None
}
}
}
#[duplicate::duplicate_item(
Integer Failable;
[i8] [true];
[i16] [true];
[i64] [false];
[i128] [false];
[isize] [false];
[u8] [true];
[u16] [true];
[u32] [true];
[u64] [false];
[u128] [false];
[usize] [false];
)]
impl<'a> FromScriptModuleParam<'a> for Integer {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
let value = param.get_param_int(index);
comptime_if::comptime_if!(
if failable where (failable = Failable) {
value.try_into().ok()
} else {
Some(value as Integer)
}
)
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for f64 {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(param.get_param_float(index))
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for f32 {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(param.get_param_float(index) as f32)
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for bool {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(param.get_param_boolean(index))
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for String {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
param.get_param_str(index)
} else {
None
}
}
}
impl<'a, T> FromScriptModuleParam<'a> for NonNull<T> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
param.get_param_data(index)
} else {
None
}
}
}
#[duplicate::duplicate_item(
Integer NonZero Failable;
[i8] [NonZeroI8] [true];
[i16] [NonZeroI16] [true];
[i64] [NonZeroI64] [false];
[i128] [NonZeroI128] [false];
[isize] [NonZeroIsize] [false];
[u8] [NonZeroU8] [true];
[u16] [NonZeroU16] [true];
[u32] [NonZeroU32] [true];
[u64] [NonZeroU64] [false];
[u128] [NonZeroU128] [false];
[usize] [NonZeroUsize] [false];
)]
impl<'a> FromScriptModuleParam<'a> for NonZero {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
let value: Integer = comptime_if::comptime_if!(
if failable where (failable = Failable) {
param.get_param_int(index).try_into().ok()?
} else {
param.get_param_int(index) as Integer
}
);
NonZero::new(value)
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for NonZeroI32 {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
NonZeroI32::new(param.get_param_int(index))
} else {
None
}
}
}
impl<'a, T> FromScriptModuleParam<'a> for Option<T>
where
T: FromScriptModuleParam<'a>,
{
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(T::from_param(param, index))
} else {
None
}
}
}
pub struct ScriptModuleParamArray<'a> {
index: usize,
ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
marker: std::marker::PhantomData<&'a ()>,
}
impl std::fmt::Debug for ScriptModuleParamArray<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ScriptModuleParamArray")
.field("index", &self.index)
.field("len", &self.len())
.finish()
}
}
impl<'a> ScriptModuleParamArray<'a> {
pub fn len(&self) -> usize {
unsafe { ((*self.ptr).get_param_array_num)(self.index as i32) as usize }
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get_int(&self, array_index: usize) -> i32 {
unsafe { ((*self.ptr).get_param_array_int)(self.index as i32, array_index as i32) }
}
pub fn get_float(&self, array_index: usize) -> f64 {
unsafe { ((*self.ptr).get_param_array_double)(self.index as i32, array_index as i32) }
}
pub fn get_str(&self, array_index: usize) -> Option<String> {
unsafe {
let c_str = ((*self.ptr).get_param_array_string)(self.index as i32, array_index as i32);
if c_str.is_null() {
None
} else {
Some(
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned(),
)
}
}
}
}
impl<'a> FromScriptModuleParam<'a> for ScriptModuleParamArray<'a> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(ScriptModuleParamArray {
index,
ptr: param.internal,
marker: std::marker::PhantomData,
})
} else {
None
}
}
}
#[derive(Debug)]
pub struct ScriptModuleParamTable<'a> {
index: usize,
ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
marker: std::marker::PhantomData<&'a ()>,
}
impl<'a> ScriptModuleParamTable<'a> {
pub fn get_int(&self, key: &str) -> i32 {
let c_key = std::ffi::CString::new(key).unwrap();
unsafe { ((*self.ptr).get_param_table_int)(self.index as i32, c_key.as_ptr()) }
}
pub fn get_float(&self, key: &str) -> f64 {
let c_key = std::ffi::CString::new(key).unwrap();
unsafe { ((*self.ptr).get_param_table_double)(self.index as i32, c_key.as_ptr()) }
}
pub fn get_str(&self, key: &str) -> Option<String> {
let c_key = std::ffi::CString::new(key).unwrap();
unsafe {
let c_str = ((*self.ptr).get_param_table_string)(self.index as i32, c_key.as_ptr());
if c_str.is_null() {
None
} else {
Some(
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned(),
)
}
}
}
}
impl<'a> FromScriptModuleParam<'a> for ScriptModuleParamTable<'a> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
if index < param.len() {
Some(ScriptModuleParamTable {
index,
ptr: param.internal,
marker: std::marker::PhantomData,
})
} else {
None
}
}
}
impl<'a> FromScriptModuleParam<'a> for Vec<String> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
let array = ScriptModuleParamArray::from_param(param, index)?;
let mut result = Vec::new();
for i in 0..array.len() {
result.push(array.get_str(i)?);
}
Some(result)
}
}
impl<'a> FromScriptModuleParam<'a> for Vec<i32> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
let array = ScriptModuleParamArray::from_param(param, index)?;
let mut result = Vec::new();
for i in 0..array.len() {
result.push(array.get_int(i));
}
Some(result)
}
}
impl<'a> FromScriptModuleParam<'a> for Vec<f64> {
fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
let array = ScriptModuleParamArray::from_param(param, index)?;
let mut result = Vec::new();
for i in 0..array.len() {
result.push(array.get_float(i));
}
Some(result)
}
}
pub trait FromScriptModuleParamTable<'a>: Sized {
fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self>;
}
impl<'a> FromScriptModuleParamTable<'a> for i32 {
fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
Some(param.get_int(key))
}
}
impl<'a> FromScriptModuleParamTable<'a> for f64 {
fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
Some(param.get_float(key))
}
}
impl<'a> FromScriptModuleParamTable<'a> for String {
fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
param.get_str(key)
}
}
impl<'a, T: FromScriptModuleParamTable<'a>> FromScriptModuleParamTable<'a> for Option<T> {
fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
Some(T::from_param_table(param, key))
}
}
#[derive(Debug, Clone)]
pub enum ScriptModuleReturnValue {
Int(i32),
Float(f64),
String(String),
Boolean(bool),
Data(*const std::ffi::c_void),
StringArray(Vec<String>),
IntArray(Vec<i32>),
FloatArray(Vec<f64>),
IntTable(std::collections::HashMap<String, i32>),
FloatTable(std::collections::HashMap<String, f64>),
StringTable(std::collections::HashMap<String, String>),
}
#[derive(thiserror::Error, Debug)]
pub enum IntoScriptModuleReturnValueError<T> {
#[error("failed to convert value: {0}")]
ConversionFailed(#[source] T),
#[error("failed to push return value: {0}")]
PushFailed(#[from] ScriptModuleCallHandleError),
}
pub trait IntoScriptModuleReturnValue
where
Self: Sized,
{
type Err: Send + Sync + 'static + Into<Box<dyn std::error::Error + Send + Sync + 'static>>;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err>;
fn push_into(
self,
param: &mut ScriptModuleCallHandle,
) -> Result<(), IntoScriptModuleReturnValueError<Self::Err>> {
for value in self
.into_return_values()
.map_err(IntoScriptModuleReturnValueError::ConversionFailed)?
{
match value {
ScriptModuleReturnValue::Int(v) => {
param.push_result_int(v);
}
ScriptModuleReturnValue::Float(v) => {
param.push_result_float(v);
}
ScriptModuleReturnValue::String(v) => {
param.push_result_str(&v)?;
}
ScriptModuleReturnValue::Boolean(v) => {
param.push_result_boolean(v);
}
ScriptModuleReturnValue::Data(v) => {
param.push_result_data(v);
}
ScriptModuleReturnValue::StringArray(v) => {
let strs: Vec<&str> = v.iter().map(|s| s.as_str()).collect();
param.push_result_array_str(&strs)?
}
ScriptModuleReturnValue::IntArray(v) => param.push_result_array_int(&v)?,
ScriptModuleReturnValue::FloatArray(v) => param.push_result_array_float(&v)?,
ScriptModuleReturnValue::IntTable(v) => {
let table = v.iter().map(|(k, v)| (k.as_str(), *v));
param.push_result_table_int(table)?;
}
ScriptModuleReturnValue::FloatTable(v) => {
let table = v.iter().map(|(k, v)| (k.as_str(), *v));
param.push_result_table_float(table)?;
}
ScriptModuleReturnValue::StringTable(v) => {
let table = v.iter().map(|(k, v)| (k.as_str(), v.as_str()));
param.push_result_table_str(table)?;
}
};
}
Ok(())
}
}
pub use aviutl2_macros::IntoScriptModuleReturnValue;
impl<T> IntoScriptModuleReturnValue for *const T {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Data(
self as *const std::ffi::c_void,
)])
}
}
impl IntoScriptModuleReturnValue for i32 {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Int(self)])
}
}
#[duplicate::duplicate_item(
Integer;
[i8];
[i16];
[u8];
[u16];
)]
impl IntoScriptModuleReturnValue for Integer {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Int(self as i32)])
}
}
#[duplicate::duplicate_item(
Integer;
[i64];
[i128];
[isize];
[u32];
[u64];
[u128];
[usize];
)]
impl IntoScriptModuleReturnValue for Integer {
type Err = std::num::TryFromIntError;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Int(self.try_into()?)])
}
}
impl IntoScriptModuleReturnValue for f64 {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Float(self)])
}
}
impl IntoScriptModuleReturnValue for f32 {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Float(self as f64)])
}
}
impl IntoScriptModuleReturnValue for bool {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::Boolean(self)])
}
}
impl IntoScriptModuleReturnValue for &str {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::String(self.to_string())])
}
}
impl IntoScriptModuleReturnValue for String {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::String(self)])
}
}
impl IntoScriptModuleReturnValue for ScriptModuleReturnValue {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![self])
}
}
impl IntoScriptModuleReturnValue for Vec<ScriptModuleReturnValue> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(self)
}
}
impl<T: IntoScriptModuleReturnValue> IntoScriptModuleReturnValue for Option<T> {
type Err = T::Err;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
if let Some(value) = self {
value.into_return_values()
} else {
Ok(Vec::new())
}
}
}
impl<T, const N: usize> IntoScriptModuleReturnValue for [T; N]
where
Vec<T>: IntoScriptModuleReturnValue,
{
type Err = <Vec<T> as IntoScriptModuleReturnValue>::Err;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
let vec: Vec<T> = self.into();
vec.into_return_values()
}
}
impl<T: IntoScriptModuleReturnValue, E> IntoScriptModuleReturnValue for Result<T, E>
where
E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
{
type Err = T::Err;
fn into_return_values(
self,
) -> Result<
Vec<ScriptModuleReturnValue>,
<std::result::Result<T, E> as IntoScriptModuleReturnValue>::Err,
> {
match self {
Ok(value) => value.into_return_values(),
Err(_) => Ok(Vec::new()),
}
}
fn push_into(
self,
param: &mut ScriptModuleCallHandle,
) -> Result<
(),
IntoScriptModuleReturnValueError<
<std::result::Result<T, E> as IntoScriptModuleReturnValue>::Err,
>,
> {
match self {
Ok(value) => value.push_into(param)?,
Err(err) => {
let e: Box<dyn std::error::Error + 'static> = err.into();
let e = e.to_string();
param.set_error(&e)?
}
}
Ok(())
}
}
impl IntoScriptModuleReturnValue for () {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(Vec::new())
}
}
macro_rules! impl_into_script_module_return_value_for_tuple {
($($name:ident),+) => {
impl<$($name),+> IntoScriptModuleReturnValue for ($($name,)+)
where
$($name: IntoScriptModuleReturnValue),+
{
type Err = anyhow::Error;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
let mut vec = Vec::new();
#[allow(non_snake_case)]
let ($($name,)+) = self;
$(
vec.extend(
$name.into_return_values()
.map_err(|e| anyhow::Error::from_boxed(e.into()))?
);
)+
Ok(vec)
}
}
};
}
impl_into_script_module_return_value_for_tuple!(T1);
impl_into_script_module_return_value_for_tuple!(T1, T2);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
impl IntoScriptModuleReturnValue for Vec<String> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::StringArray(self)])
}
}
impl IntoScriptModuleReturnValue for Vec<&str> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::StringArray(
self.iter().map(|s| s.to_string()).collect(),
)])
}
}
impl IntoScriptModuleReturnValue for Vec<i32> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::IntArray(self)])
}
}
impl IntoScriptModuleReturnValue for Vec<f64> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::FloatArray(self)])
}
}
impl<T> IntoScriptModuleReturnValue for &[T]
where
Vec<T>: IntoScriptModuleReturnValue,
T: Clone,
{
type Err = <Vec<T> as IntoScriptModuleReturnValue>::Err;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
let vec: Vec<T> = self.to_vec();
vec.into_return_values()
}
}
impl IntoScriptModuleReturnValue for std::collections::HashMap<String, i32> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::IntTable(self)])
}
}
impl IntoScriptModuleReturnValue for std::collections::HashMap<String, f64> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::FloatTable(self)])
}
}
impl IntoScriptModuleReturnValue for std::collections::HashMap<String, String> {
type Err = std::convert::Infallible;
fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
Ok(vec![ScriptModuleReturnValue::StringTable(self)])
}
}
#[doc(hidden)]
pub mod __table_converter {
pub trait ToOptionalTableEntry {
type Value;
fn to_optional(&self) -> Option<Self::Value>;
}
impl<T: Clone> ToOptionalTableEntry for Option<T> {
type Value = T;
fn to_optional(&self) -> Option<Self::Value> {
self.clone()
}
}
impl ToOptionalTableEntry for i32 {
type Value = i32;
fn to_optional(&self) -> Option<Self::Value> {
Some(*self)
}
}
impl ToOptionalTableEntry for f64 {
type Value = f64;
fn to_optional(&self) -> Option<Self::Value> {
Some(*self)
}
}
impl ToOptionalTableEntry for String {
type Value = String;
fn to_optional(&self) -> Option<Self::Value> {
Some(self.clone())
}
}
}
#[doc(hidden)]
pub fn __push_return_value<T>(param: &mut crate::module::ScriptModuleCallHandle, value: T)
where
T: crate::module::IntoScriptModuleReturnValue,
{
let res = value.push_into(param);
let _ = res
.map_err(|e| -> Box<dyn std::error::Error + Send + Sync + 'static> {
match e {
crate::module::IntoScriptModuleReturnValueError::PushFailed(e) => Box::new(e),
crate::module::IntoScriptModuleReturnValueError::ConversionFailed(e) => e.into(),
}
})
.push_into(param);
}