rune/runtime/
guarded_args.rs1use crate::alloc::Vec;
2use crate::runtime::Args;
3use crate::runtime::{Stack, UnsafeToValue, Value, VmError};
4
5pub trait GuardedArgs {
11 type Guard;
13
14 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> Result<Self::Guard, VmError>;
22
23 unsafe fn guarded_into_vec(self) -> Result<(Vec<Value>, Self::Guard), VmError>;
31
32 fn count(&self) -> usize;
34}
35
36macro_rules! impl_into_args {
37 ($count:expr $(, $ty:ident $value:ident $_:expr)*) => {
38 impl<$($ty,)*> GuardedArgs for ($($ty,)*)
39 where
40 $($ty: UnsafeToValue,)*
41 {
42 type Guard = ($($ty::Guard,)*);
43
44 #[allow(unused)]
45 #[inline]
46 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> Result<Self::Guard, VmError> {
47 let ($($value,)*) = self;
48 $(let $value = $value.unsafe_to_value()?;)*
49 $(stack.push($value.0)?;)*
50 Ok(($($value.1,)*))
51 }
52
53 #[allow(unused)]
54 #[inline]
55 unsafe fn guarded_into_vec(self) -> Result<(Vec<Value>, Self::Guard), VmError> {
56 let ($($value,)*) = self;
57 $(let $value = $value.unsafe_to_value()?;)*
58 let mut out = Vec::try_with_capacity($count)?;
59 $(out.try_push($value.0)?;)*
60 Ok((out, ($($value.1,)*)))
61 }
62
63 #[inline]
64 fn count(&self) -> usize {
65 $count
66 }
67 }
68 };
69}
70
71repeat_macro!(impl_into_args);
72
73impl GuardedArgs for Vec<Value> {
74 type Guard = ();
75
76 #[inline]
77 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> Result<Self::Guard, VmError> {
78 self.into_stack(stack)
79 }
80
81 #[inline]
82 unsafe fn guarded_into_vec(self) -> Result<(Vec<Value>, Self::Guard), VmError> {
83 Ok((self, ()))
84 }
85
86 #[inline]
87 fn count(&self) -> usize {
88 (self as &dyn Args).count()
89 }
90}
91
92impl GuardedArgs for rust_alloc::vec::Vec<Value> {
93 type Guard = ();
94
95 #[inline]
96 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> Result<Self::Guard, VmError> {
97 self.into_stack(stack)
98 }
99
100 #[inline]
101 unsafe fn guarded_into_vec(self) -> Result<(Vec<Value>, Self::Guard), VmError> {
102 Ok((Vec::try_from(self)?, ()))
103 }
104
105 #[inline]
106 fn count(&self) -> usize {
107 self.len()
108 }
109}