aviutl2\module/
param.rs

1/// 関数の引数・返り値を扱うための型とトレイト。
2#[derive(Debug)]
3pub struct ScriptModuleCallHandle {
4    pub(crate) internal: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
5}
6
7/// [`ScriptModuleCallHandle`]関連のエラー。
8#[derive(thiserror::Error, Debug)]
9pub enum ScriptModuleCallHandleError {
10    #[error("key contains null byte")]
11    KeyContainsNullByte(std::ffi::NulError),
12
13    #[error("value contains null byte")]
14    ValueContainsNullByte(std::ffi::NulError),
15
16    #[error("too many elements")]
17    TooManyElements,
18}
19
20pub type ScriptModuleCallHandleResult<T> = std::result::Result<T, ScriptModuleCallHandleError>;
21
22impl ScriptModuleCallHandle {
23    /// ポインタから`ScriptModuleParam`を作成する。
24    ///
25    /// # Safety
26    ///
27    /// `ptr`は有効な`SCRIPT_MODULE_PARAM`へのポインタである必要があります。
28    pub unsafe fn from_ptr(
29        ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
30    ) -> ScriptModuleCallHandle {
31        ScriptModuleCallHandle { internal: ptr }
32    }
33
34    /// 引数の数を返す。
35    pub fn len(&self) -> usize {
36        unsafe { ((*self.internal).get_param_num)() as usize }
37    }
38
39    /// 引数が与えられていないかを返す。
40    pub fn is_empty(&self) -> bool {
41        self.len() == 0
42    }
43
44    /// 引数を取得する。
45    pub fn get_param<'a, T: FromScriptModuleParam<'a>>(&'a self, index: usize) -> Option<T> {
46        T::from_param(self, index)
47    }
48
49    /// 引数を整数として取得する。
50    ///
51    /// # Note
52    ///
53    /// 引数を取得できない場合は0を返します。
54    pub fn get_param_int(&self, index: usize) -> i32 {
55        unsafe { ((*self.internal).get_param_int)(index as i32) }
56    }
57
58    /// 引数を浮動小数点数として取得する。
59    ///
60    /// # Note
61    ///
62    /// 引数を取得できない場合は0.0を返します。
63    pub fn get_param_float(&self, index: usize) -> f64 {
64        unsafe { ((*self.internal).get_param_double)(index as i32) }
65    }
66
67    /// 引数を文字列として取得する。
68    pub fn get_param_str(&self, index: usize) -> Option<String> {
69        unsafe {
70            let c_str = ((*self.internal).get_param_string)(index as i32);
71            if c_str.is_null() {
72                None
73            } else {
74                Some(
75                    std::ffi::CStr::from_ptr(c_str)
76                        .to_string_lossy()
77                        .into_owned(),
78                )
79            }
80        }
81    }
82
83    /// 引数をデータポインタとして取得する。
84    ///
85    /// # Note
86    ///
87    /// 引数を取得できない場合は`None`を返します。
88    pub fn get_param_data<T>(&self, index: usize) -> Option<*mut T> {
89        unsafe {
90            let data_ptr = ((*self.internal).get_param_data)(index as i32);
91            if data_ptr.is_null() {
92                None
93            } else {
94                Some(data_ptr as *mut T)
95            }
96        }
97    }
98
99    /// 引数をブール値として取得する。
100    ///
101    /// # Note
102    ///
103    /// 引数を取得できない場合は`false`を返します。
104    pub fn get_param_boolean(&self, index: usize) -> bool {
105        unsafe { ((*self.internal).get_param_boolean)(index as i32) }
106    }
107
108    /// 引数のテーブルの要素を整数として取得する。
109    ///
110    /// # Note
111    ///
112    /// 引数を取得できない場合は0を返します。
113    pub fn get_param_table_int(
114        &self,
115        index: usize,
116        key: &str,
117    ) -> ScriptModuleCallHandleResult<i32> {
118        let c_key = std::ffi::CString::new(key)
119            .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
120        Ok(unsafe { ((*self.internal).get_param_table_int)(index as i32, c_key.as_ptr()) })
121    }
122
123    /// 引数のテーブルの要素を浮動小数点数として取得する。
124    ///
125    /// # Note
126    ///
127    /// 引数を取得できない場合は0.0を返します。
128    pub fn get_param_table_float(
129        &self,
130        index: usize,
131        key: &str,
132    ) -> ScriptModuleCallHandleResult<f64> {
133        let c_key = std::ffi::CString::new(key)
134            .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
135        Ok(unsafe { ((*self.internal).get_param_table_double)(index as i32, c_key.as_ptr()) })
136    }
137
138    /// 引数のテーブルの要素を文字列として取得する。
139    pub fn get_param_table_str(
140        &self,
141        index: usize,
142        key: &str,
143    ) -> ScriptModuleCallHandleResult<Option<String>> {
144        let c_key = std::ffi::CString::new(key)
145            .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
146        unsafe {
147            let c_str = ((*self.internal).get_param_table_string)(index as i32, c_key.as_ptr());
148            Ok(if c_str.is_null() {
149                None
150            } else {
151                Some(
152                    std::ffi::CStr::from_ptr(c_str)
153                        .to_string_lossy()
154                        .into_owned(),
155                )
156            })
157        }
158    }
159
160    /// 引数の配列の要素の数を取得する。
161    pub fn get_param_array_len(&self, index: usize) -> usize {
162        unsafe { ((*self.internal).get_param_array_num)(index as i32) as usize }
163    }
164
165    /// 引数の配列の要素を数値として取得する。
166    pub fn get_param_array_int(&self, index: usize, array_index: usize) -> i32 {
167        unsafe { ((*self.internal).get_param_array_int)(index as i32, array_index as i32) }
168    }
169
170    /// 引数の配列の要素を浮動小数点数として取得する。
171    pub fn get_param_array_float(&self, index: usize, array_index: usize) -> f64 {
172        unsafe { ((*self.internal).get_param_array_double)(index as i32, array_index as i32) }
173    }
174
175    /// 引数の配列の要素を文字列として取得する。
176    pub fn get_param_array_str(&self, index: usize, array_index: usize) -> Option<String> {
177        unsafe {
178            let c_str = ((*self.internal).get_param_array_string)(index as i32, array_index as i32);
179            if c_str.is_null() {
180                None
181            } else {
182                Some(
183                    std::ffi::CStr::from_ptr(c_str)
184                        .to_string_lossy()
185                        .into_owned(),
186                )
187            }
188        }
189    }
190
191    /// 関数のエラーを設定する。
192    pub fn set_error(&mut self, message: &str) -> ScriptModuleCallHandleResult<()> {
193        let c_message = std::ffi::CString::new(message)
194            .map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
195        unsafe {
196            ((*self.internal).set_error)(c_message.as_ptr());
197        }
198        Ok(())
199    }
200
201    /// 関数の返り値を追加する。
202    pub fn push_result<T: IntoScriptModuleReturnValue>(
203        &mut self,
204        value: T,
205    ) -> Result<(), IntoScriptModuleReturnValueError<T::Err>> {
206        value.push_into(self)
207    }
208
209    /// 関数の返り値に整数を追加する。
210    pub fn push_result_int(&mut self, value: i32) {
211        unsafe {
212            ((*self.internal).push_result_int)(value);
213        }
214    }
215
216    /// 関数の返り値に浮動小数点数を追加する。
217    pub fn push_result_float(&mut self, value: f64) {
218        unsafe {
219            ((*self.internal).push_result_double)(value);
220        }
221    }
222
223    /// 関数の返り値に文字列を追加する。
224    pub fn push_result_str(&mut self, value: &str) -> ScriptModuleCallHandleResult<()> {
225        let c_value = std::ffi::CString::new(value)
226            .map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
227        unsafe {
228            ((*self.internal).push_result_string)(c_value.as_ptr());
229        }
230        Ok(())
231    }
232
233    /// 関数の返り値に整数の連想配列を追加する。
234    pub fn push_result_table_int<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
235    where
236        T: std::iter::IntoIterator<Item = (&'a str, i32)>,
237    {
238        let mut keys = Vec::new();
239        let mut values = Vec::new();
240        for (key, value) in table {
241            let c_key = std::ffi::CString::new(key)
242                .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
243            keys.push(c_key);
244            values.push(value);
245        }
246        let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
247        unsafe {
248            ((*self.internal).push_result_table_int)(
249                key_ptrs.as_ptr(),
250                values.as_ptr(),
251                key_ptrs.len() as i32,
252            );
253        }
254        Ok(())
255    }
256
257    /// 関数の返り値に浮動小数点数の連想配列を追加する。
258    pub fn push_result_table_float<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
259    where
260        T: std::iter::IntoIterator<Item = (&'a str, f64)>,
261    {
262        let mut keys = Vec::new();
263        let mut values = Vec::new();
264        for (key, value) in table {
265            let c_key = std::ffi::CString::new(key)
266                .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
267            keys.push(c_key);
268            values.push(value);
269        }
270        let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
271        unsafe {
272            ((*self.internal).push_result_table_double)(
273                key_ptrs.as_ptr(),
274                values.as_ptr(),
275                key_ptrs.len() as i32,
276            );
277        }
278        Ok(())
279    }
280
281    /// 関数の返り値に文字列の連想配列を追加する。
282    pub fn push_result_table_str<'a, T>(&mut self, table: T) -> ScriptModuleCallHandleResult<()>
283    where
284        T: std::iter::IntoIterator<Item = (&'a str, &'a str)>,
285    {
286        let mut keys = Vec::new();
287        let mut values = Vec::new();
288        for (key, value) in table {
289            let c_key = std::ffi::CString::new(key)
290                .map_err(ScriptModuleCallHandleError::KeyContainsNullByte)?;
291            let c_value = std::ffi::CString::new(value)
292                .map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
293            keys.push(c_key);
294            values.push(c_value);
295        }
296        if keys.len() > i32::MAX as usize {
297            return Err(ScriptModuleCallHandleError::TooManyElements);
298        }
299        let key_ptrs: Vec<*const std::os::raw::c_char> = keys.iter().map(|k| k.as_ptr()).collect();
300        let value_ptrs: Vec<*const std::os::raw::c_char> =
301            values.iter().map(|v| v.as_ptr()).collect();
302        unsafe {
303            ((*self.internal).push_result_table_string)(
304                key_ptrs.as_ptr(),
305                value_ptrs.as_ptr(),
306                key_ptrs.len() as i32,
307            );
308        }
309        Ok(())
310    }
311
312    /// 関数の返り値に整数の配列を追加する。
313    pub fn push_result_array_int(&mut self, values: &[i32]) -> ScriptModuleCallHandleResult<()> {
314        if values.len() > i32::MAX as usize {
315            return Err(ScriptModuleCallHandleError::TooManyElements);
316        }
317        unsafe {
318            ((*self.internal).push_result_array_int)(values.as_ptr(), values.len() as i32);
319        }
320        Ok(())
321    }
322
323    /// 関数の返り値に浮動小数点数の配列を追加する。
324    pub fn push_result_array_float(&mut self, values: &[f64]) -> ScriptModuleCallHandleResult<()> {
325        if values.len() > i32::MAX as usize {
326            return Err(ScriptModuleCallHandleError::TooManyElements);
327        }
328        unsafe {
329            ((*self.internal).push_result_array_double)(values.as_ptr(), values.len() as i32);
330        }
331        Ok(())
332    }
333
334    /// 関数の返り値に文字列の配列を追加する。
335    pub fn push_result_array_str(&mut self, values: &[&str]) -> ScriptModuleCallHandleResult<()> {
336        let c_values: Vec<std::ffi::CString> = values
337            .iter()
338            .map(|s| std::ffi::CString::new(*s))
339            .collect::<Result<_, _>>()
340            .map_err(ScriptModuleCallHandleError::ValueContainsNullByte)?;
341        if c_values.len() > i32::MAX as usize {
342            return Err(ScriptModuleCallHandleError::TooManyElements);
343        }
344        let c_value_ptrs: Vec<*const std::os::raw::c_char> =
345            c_values.iter().map(|s| s.as_ptr()).collect();
346        unsafe {
347            ((*self.internal).push_result_array_string)(
348                c_value_ptrs.as_ptr(),
349                c_value_ptrs.len() as i32,
350            );
351        }
352        Ok(())
353    }
354
355    /// 関数の返り値にブール値を追加する。
356    pub fn push_result_boolean(&mut self, value: bool) {
357        unsafe {
358            ((*self.internal).push_result_boolean)(value);
359        }
360    }
361}
362impl From<*mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM> for ScriptModuleCallHandle {
363    fn from(ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM) -> Self {
364        Self { internal: ptr }
365    }
366}
367
368/// スクリプトモジュールの引数として受け取れる値。
369///
370/// # Note
371///
372/// このtraitはDeriveマクロを使用して実装することもできます。
373/// 詳細は[`derive@FromScriptModuleParam`]のドキュメントを参照してください。
374pub trait FromScriptModuleParam<'a>: Sized {
375    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self>;
376}
377pub use aviutl2_macros::FromScriptModuleParam;
378
379impl<'a> FromScriptModuleParam<'a> for i32 {
380    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
381        if index < param.len() {
382            Some(param.get_param_int(index))
383        } else {
384            None
385        }
386    }
387}
388impl<'a> FromScriptModuleParam<'a> for f64 {
389    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
390        if index < param.len() {
391            Some(param.get_param_float(index))
392        } else {
393            None
394        }
395    }
396}
397impl<'a> FromScriptModuleParam<'a> for bool {
398    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
399        if index < param.len() {
400            Some(param.get_param_boolean(index))
401        } else {
402            None
403        }
404    }
405}
406impl<'a> FromScriptModuleParam<'a> for String {
407    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
408        if index < param.len() {
409            param.get_param_str(index)
410        } else {
411            None
412        }
413    }
414}
415
416impl<'a, T> FromScriptModuleParam<'a> for Option<T>
417where
418    T: FromScriptModuleParam<'a>,
419{
420    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
421        if index < param.len() {
422            Some(T::from_param(param, index))
423        } else {
424            None
425        }
426    }
427}
428
429/// スクリプトモジュールの引数として渡される配列。
430pub struct ScriptModuleParamArray<'a> {
431    index: usize,
432    ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
433    marker: std::marker::PhantomData<&'a ()>,
434}
435
436impl std::fmt::Debug for ScriptModuleParamArray<'_> {
437    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438        f.debug_struct("ScriptModuleParamArray")
439            .field("index", &self.index)
440            .field("len", &self.len())
441            .finish()
442    }
443}
444
445impl<'a> ScriptModuleParamArray<'a> {
446    /// 配列の長さを返す。
447    pub fn len(&self) -> usize {
448        unsafe { ((*self.ptr).get_param_array_num)(self.index as i32) as usize }
449    }
450
451    /// 配列が空かどうかを返す。
452    pub fn is_empty(&self) -> bool {
453        self.len() == 0
454    }
455
456    /// 配列の要素を整数として取得する。
457    pub fn get_int(&self, array_index: usize) -> i32 {
458        unsafe { ((*self.ptr).get_param_array_int)(self.index as i32, array_index as i32) }
459    }
460
461    /// 配列の要素を浮動小数点数として取得する。
462    pub fn get_float(&self, array_index: usize) -> f64 {
463        unsafe { ((*self.ptr).get_param_array_double)(self.index as i32, array_index as i32) }
464    }
465
466    /// 配列の要素を文字列として取得する。
467    pub fn get_str(&self, array_index: usize) -> Option<String> {
468        unsafe {
469            let c_str = ((*self.ptr).get_param_array_string)(self.index as i32, array_index as i32);
470            if c_str.is_null() {
471                None
472            } else {
473                Some(
474                    std::ffi::CStr::from_ptr(c_str)
475                        .to_string_lossy()
476                        .into_owned(),
477                )
478            }
479        }
480    }
481}
482
483impl<'a> FromScriptModuleParam<'a> for ScriptModuleParamArray<'a> {
484    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
485        if index < param.len() {
486            Some(ScriptModuleParamArray {
487                index,
488                ptr: param.internal,
489                marker: std::marker::PhantomData,
490            })
491        } else {
492            None
493        }
494    }
495}
496
497/// スクリプトモジュールの引数として渡される連想配列。
498#[derive(Debug)]
499pub struct ScriptModuleParamTable<'a> {
500    index: usize,
501    ptr: *mut aviutl2_sys::module2::SCRIPT_MODULE_PARAM,
502    marker: std::marker::PhantomData<&'a ()>,
503}
504
505impl<'a> ScriptModuleParamTable<'a> {
506    /// 連想配列の要素を整数として取得する。
507    pub fn get_int(&self, key: &str) -> i32 {
508        let c_key = std::ffi::CString::new(key).unwrap();
509        unsafe { ((*self.ptr).get_param_table_int)(self.index as i32, c_key.as_ptr()) }
510    }
511
512    /// 連想配列の要素を浮動小数点数として取得する。
513    pub fn get_float(&self, key: &str) -> f64 {
514        let c_key = std::ffi::CString::new(key).unwrap();
515        unsafe { ((*self.ptr).get_param_table_double)(self.index as i32, c_key.as_ptr()) }
516    }
517
518    /// 連想配列の要素を文字列として取得する。
519    pub fn get_str(&self, key: &str) -> Option<String> {
520        let c_key = std::ffi::CString::new(key).unwrap();
521        unsafe {
522            let c_str = ((*self.ptr).get_param_table_string)(self.index as i32, c_key.as_ptr());
523            if c_str.is_null() {
524                None
525            } else {
526                Some(
527                    std::ffi::CStr::from_ptr(c_str)
528                        .to_string_lossy()
529                        .into_owned(),
530                )
531            }
532        }
533    }
534}
535
536impl<'a> FromScriptModuleParam<'a> for ScriptModuleParamTable<'a> {
537    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
538        if index < param.len() {
539            Some(ScriptModuleParamTable {
540                index,
541                ptr: param.internal,
542                marker: std::marker::PhantomData,
543            })
544        } else {
545            None
546        }
547    }
548}
549
550impl<'a> FromScriptModuleParam<'a> for Vec<String> {
551    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
552        let array = ScriptModuleParamArray::from_param(param, index)?;
553        let mut result = Vec::new();
554        for i in 0..array.len() {
555            result.push(array.get_str(i)?);
556        }
557        Some(result)
558    }
559}
560impl<'a> FromScriptModuleParam<'a> for Vec<i32> {
561    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
562        let array = ScriptModuleParamArray::from_param(param, index)?;
563        let mut result = Vec::new();
564        for i in 0..array.len() {
565            result.push(array.get_int(i));
566        }
567        Some(result)
568    }
569}
570impl<'a> FromScriptModuleParam<'a> for Vec<f64> {
571    fn from_param(param: &'a ScriptModuleCallHandle, index: usize) -> Option<Self> {
572        let array = ScriptModuleParamArray::from_param(param, index)?;
573        let mut result = Vec::new();
574        for i in 0..array.len() {
575            result.push(array.get_float(i));
576        }
577        Some(result)
578    }
579}
580
581/// 連想配列の値として使える型。
582pub trait FromScriptModuleParamTable<'a>: Sized {
583    fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self>;
584}
585
586impl<'a> FromScriptModuleParamTable<'a> for i32 {
587    fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
588        Some(param.get_int(key))
589    }
590}
591impl<'a> FromScriptModuleParamTable<'a> for f64 {
592    fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
593        Some(param.get_float(key))
594    }
595}
596impl<'a> FromScriptModuleParamTable<'a> for String {
597    fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
598        param.get_str(key)
599    }
600}
601impl<'a, T: FromScriptModuleParamTable<'a>> FromScriptModuleParamTable<'a> for Option<T> {
602    fn from_param_table(param: &'a ScriptModuleParamTable, key: &str) -> Option<Self> {
603        Some(T::from_param_table(param, key))
604    }
605}
606
607/// スクリプトモジュールの関数の戻り値の型を表す列挙型。
608#[derive(Debug, Clone)]
609pub enum ScriptModuleReturnValue {
610    Int(i32),
611    Float(f64),
612    String(String),
613    Boolean(bool),
614    StringArray(Vec<String>),
615    IntArray(Vec<i32>),
616    FloatArray(Vec<f64>),
617    IntTable(std::collections::HashMap<String, i32>),
618    FloatTable(std::collections::HashMap<String, f64>),
619    StringTable(std::collections::HashMap<String, String>),
620}
621
622/// [`IntoScriptModuleReturnValue::push_into`]で使われるエラー。
623#[derive(thiserror::Error, Debug)]
624pub enum IntoScriptModuleReturnValueError<T> {
625    #[error("failed to convert value: {0}")]
626    ConversionFailed(#[source] T),
627    #[error("failed to push return value: {0}")]
628    PushFailed(#[from] ScriptModuleCallHandleError),
629}
630
631/// 関数の戻り値として使える型。
632///
633/// # Note
634///
635/// この関数はDeriveマクロを使用して実装することもできます。
636/// 詳細は[`derive@IntoScriptModuleReturnValue`]のドキュメントを参照してください。
637pub trait IntoScriptModuleReturnValue
638where
639    Self: Sized,
640{
641    type Err: Send + Sync + 'static + Into<Box<dyn std::error::Error + Send + Sync + 'static>>;
642
643    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err>;
644    fn push_into(
645        self,
646        param: &mut ScriptModuleCallHandle,
647    ) -> Result<(), IntoScriptModuleReturnValueError<Self::Err>> {
648        for value in self
649            .into_return_values()
650            .map_err(IntoScriptModuleReturnValueError::ConversionFailed)?
651        {
652            match value {
653                ScriptModuleReturnValue::Int(v) => {
654                    param.push_result_int(v);
655                }
656                ScriptModuleReturnValue::Float(v) => {
657                    param.push_result_float(v);
658                }
659                ScriptModuleReturnValue::String(v) => {
660                    param.push_result_str(&v)?;
661                }
662                ScriptModuleReturnValue::Boolean(v) => {
663                    param.push_result_boolean(v);
664                }
665                ScriptModuleReturnValue::StringArray(v) => {
666                    let strs: Vec<&str> = v.iter().map(|s| s.as_str()).collect();
667                    param.push_result_array_str(&strs)?
668                }
669                ScriptModuleReturnValue::IntArray(v) => param.push_result_array_int(&v)?,
670                ScriptModuleReturnValue::FloatArray(v) => param.push_result_array_float(&v)?,
671                ScriptModuleReturnValue::IntTable(v) => {
672                    let table = v.iter().map(|(k, v)| (k.as_str(), *v));
673                    param.push_result_table_int(table)?;
674                }
675                ScriptModuleReturnValue::FloatTable(v) => {
676                    let table = v.iter().map(|(k, v)| (k.as_str(), *v));
677                    param.push_result_table_float(table)?;
678                }
679                ScriptModuleReturnValue::StringTable(v) => {
680                    let table = v.iter().map(|(k, v)| (k.as_str(), v.as_str()));
681                    param.push_result_table_str(table)?;
682                }
683            };
684        }
685        Ok(())
686    }
687}
688pub use aviutl2_macros::IntoScriptModuleReturnValue;
689
690impl IntoScriptModuleReturnValue for i32 {
691    type Err = std::convert::Infallible;
692
693    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
694        Ok(vec![ScriptModuleReturnValue::Int(self)])
695    }
696}
697#[duplicate::duplicate_item(
698    Integer;
699    [i8];
700    [i16];
701    [u8];
702    [u16];
703)]
704impl IntoScriptModuleReturnValue for Integer {
705    type Err = std::convert::Infallible;
706
707    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
708        Ok(vec![ScriptModuleReturnValue::Int(self as i32)])
709    }
710}
711#[duplicate::duplicate_item(
712    Integer;
713    [i64];
714    [i128];
715    [isize];
716    [u32];
717    [u64];
718    [u128];
719    [usize];
720)]
721impl IntoScriptModuleReturnValue for Integer {
722    type Err = std::num::TryFromIntError;
723
724    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
725        Ok(vec![ScriptModuleReturnValue::Int(self.try_into()?)])
726    }
727}
728impl IntoScriptModuleReturnValue for f64 {
729    type Err = std::convert::Infallible;
730    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
731        Ok(vec![ScriptModuleReturnValue::Float(self)])
732    }
733}
734impl IntoScriptModuleReturnValue for f32 {
735    type Err = std::convert::Infallible;
736    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
737        Ok(vec![ScriptModuleReturnValue::Float(self as f64)])
738    }
739}
740impl IntoScriptModuleReturnValue for bool {
741    type Err = std::convert::Infallible;
742    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
743        Ok(vec![ScriptModuleReturnValue::Boolean(self)])
744    }
745}
746impl IntoScriptModuleReturnValue for &str {
747    type Err = std::convert::Infallible;
748    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
749        Ok(vec![ScriptModuleReturnValue::String(self.to_string())])
750    }
751}
752impl IntoScriptModuleReturnValue for String {
753    type Err = std::convert::Infallible;
754    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
755        Ok(vec![ScriptModuleReturnValue::String(self)])
756    }
757}
758
759impl IntoScriptModuleReturnValue for ScriptModuleReturnValue {
760    type Err = std::convert::Infallible;
761    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
762        Ok(vec![self])
763    }
764}
765
766impl IntoScriptModuleReturnValue for Vec<ScriptModuleReturnValue> {
767    type Err = std::convert::Infallible;
768
769    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
770        Ok(self)
771    }
772}
773
774impl<T: IntoScriptModuleReturnValue> IntoScriptModuleReturnValue for Option<T> {
775    type Err = T::Err;
776    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
777        if let Some(value) = self {
778            value.into_return_values()
779        } else {
780            Ok(Vec::new())
781        }
782    }
783}
784impl<T, const N: usize> IntoScriptModuleReturnValue for [T; N]
785where
786    Vec<T>: IntoScriptModuleReturnValue,
787{
788    type Err = <Vec<T> as IntoScriptModuleReturnValue>::Err;
789
790    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
791        let vec: Vec<T> = self.into();
792        vec.into_return_values()
793    }
794}
795impl<T: IntoScriptModuleReturnValue, E> IntoScriptModuleReturnValue for Result<T, E>
796where
797    E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
798{
799    type Err = T::Err;
800
801    fn into_return_values(
802        self,
803    ) -> Result<
804        Vec<ScriptModuleReturnValue>,
805        <std::result::Result<T, E> as IntoScriptModuleReturnValue>::Err,
806    > {
807        match self {
808            Ok(value) => value.into_return_values(),
809            Err(_) => Ok(Vec::new()),
810        }
811    }
812    fn push_into(
813        self,
814        param: &mut ScriptModuleCallHandle,
815    ) -> Result<
816        (),
817        IntoScriptModuleReturnValueError<
818            <std::result::Result<T, E> as IntoScriptModuleReturnValue>::Err,
819        >,
820    > {
821        match self {
822            Ok(value) => value.push_into(param)?,
823            Err(err) => {
824                let e: Box<dyn std::error::Error + 'static> = err.into();
825                let e = e.to_string();
826                param.set_error(&e)?
827            }
828        }
829        Ok(())
830    }
831}
832
833impl IntoScriptModuleReturnValue for () {
834    type Err = std::convert::Infallible;
835    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
836        Ok(Vec::new())
837    }
838}
839
840macro_rules! impl_into_script_module_return_value_for_tuple {
841    ($($name:ident),+) => {
842        impl<$($name),+> IntoScriptModuleReturnValue for ($($name,)+)
843        where
844            $($name: IntoScriptModuleReturnValue),+
845        {
846            type Err = anyhow::Error;
847
848            fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
849                let mut vec = Vec::new();
850                #[allow(non_snake_case)]
851                let ($($name,)+) = self;
852                $(
853                    vec.extend(
854                        $name.into_return_values()
855                            .map_err(|e| anyhow::Error::from_boxed(e.into()))?
856                    );
857                )+
858                Ok(vec)
859            }
860        }
861    };
862}
863impl_into_script_module_return_value_for_tuple!(T1);
864impl_into_script_module_return_value_for_tuple!(T1, T2);
865impl_into_script_module_return_value_for_tuple!(T1, T2, T3);
866impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4);
867impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5);
868impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6);
869impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7);
870impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
871impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
872impl_into_script_module_return_value_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
873
874impl IntoScriptModuleReturnValue for Vec<String> {
875    type Err = std::convert::Infallible;
876    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
877        Ok(vec![ScriptModuleReturnValue::StringArray(self)])
878    }
879}
880impl IntoScriptModuleReturnValue for Vec<&str> {
881    type Err = std::convert::Infallible;
882    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
883        Ok(vec![ScriptModuleReturnValue::StringArray(
884            self.iter().map(|s| s.to_string()).collect(),
885        )])
886    }
887}
888impl IntoScriptModuleReturnValue for Vec<i32> {
889    type Err = std::convert::Infallible;
890    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
891        Ok(vec![ScriptModuleReturnValue::IntArray(self)])
892    }
893}
894impl IntoScriptModuleReturnValue for Vec<f64> {
895    type Err = std::convert::Infallible;
896    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
897        Ok(vec![ScriptModuleReturnValue::FloatArray(self)])
898    }
899}
900impl<T> IntoScriptModuleReturnValue for &[T]
901where
902    Vec<T>: IntoScriptModuleReturnValue,
903    T: Clone,
904{
905    type Err = <Vec<T> as IntoScriptModuleReturnValue>::Err;
906    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
907        let vec: Vec<T> = self.to_vec();
908        vec.into_return_values()
909    }
910}
911
912impl IntoScriptModuleReturnValue for std::collections::HashMap<String, i32> {
913    type Err = std::convert::Infallible;
914    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
915        Ok(vec![ScriptModuleReturnValue::IntTable(self)])
916    }
917}
918impl IntoScriptModuleReturnValue for std::collections::HashMap<String, f64> {
919    type Err = std::convert::Infallible;
920    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
921        Ok(vec![ScriptModuleReturnValue::FloatTable(self)])
922    }
923}
924impl IntoScriptModuleReturnValue for std::collections::HashMap<String, String> {
925    type Err = std::convert::Infallible;
926    fn into_return_values(self) -> Result<Vec<ScriptModuleReturnValue>, Self::Err> {
927        Ok(vec![ScriptModuleReturnValue::StringTable(self)])
928    }
929}
930
931#[doc(hidden)]
932pub mod __table_converter {
933    pub trait ToOptionalTableEntry {
934        type Value;
935        fn to_optional(&self) -> Option<Self::Value>;
936    }
937
938    impl<T: Clone> ToOptionalTableEntry for Option<T> {
939        type Value = T;
940        fn to_optional(&self) -> Option<Self::Value> {
941            self.clone()
942        }
943    }
944    impl ToOptionalTableEntry for i32 {
945        type Value = i32;
946        fn to_optional(&self) -> Option<Self::Value> {
947            Some(*self)
948        }
949    }
950    impl ToOptionalTableEntry for f64 {
951        type Value = f64;
952        fn to_optional(&self) -> Option<Self::Value> {
953            Some(*self)
954        }
955    }
956    impl ToOptionalTableEntry for String {
957        type Value = String;
958        fn to_optional(&self) -> Option<Self::Value> {
959            Some(self.clone())
960        }
961    }
962}
963
964#[doc(hidden)]
965pub fn __push_return_value<T>(param: &mut crate::module::ScriptModuleCallHandle, value: T)
966where
967    T: crate::module::IntoScriptModuleReturnValue,
968{
969    let res = value.push_into(param);
970    let _ = res
971        .map_err(|e| -> Box<dyn std::error::Error + Send + Sync + 'static> {
972            match e {
973                crate::module::IntoScriptModuleReturnValueError::PushFailed(e) => Box::new(e),
974                crate::module::IntoScriptModuleReturnValueError::ConversionFailed(e) => e.into(),
975            }
976        })
977        .push_into(param);
978}