1use crate::any::{Any, AnyView, ArgTryFromAnyView};
20use crate::error::Result;
21use crate::string::{Bytes, String};
22use crate::type_traits::AnyCompatible;
23
24pub trait AsPackedCallable<I, O> {
28 fn call_packed(&self, packed_args: &[AnyView]) -> Result<Any>;
30}
31
32#[inline]
33pub fn call_packed_callable<Fun, I, O>(func: Fun, packed_args: &[AnyView]) -> Result<Any>
34where
35 Fun: AsPackedCallable<I, O>,
36{
37 func.call_packed(packed_args)
38}
39
40macro_rules! impl_as_packed_callable {
41 ($len:literal; $($t:ident),*) => {
42 impl<Fun, $($t,)* Out> AsPackedCallable<($($t,)*), Out> for Fun
43 where
44 Fun: Fn($($t,)*) -> Result<Out> + 'static,
45 Any: From<Out>,
46 $($t: ArgTryFromAnyView),*
47 {
48 fn call_packed(&self, packed_args: &[AnyView]) -> Result<Any>
49 {
50 crate::ensure!(
51 packed_args.len() == $len, crate::error::VALUE_ERROR,
52 "Expected {} arguments, got {}", $len, packed_args.len()
53 );
54 let mut _arg_iter = packed_args.iter().enumerate();
56 let ret_value = self(
57 $({
58 let (i, view) = _arg_iter.next().unwrap();
60 $t::try_from_any_view(view, i)?
61 }),*
62 )?;
63 Ok(Any::from(ret_value))
64 }
65 }
66 }
67}
68
69impl_as_packed_callable!(0;);
70impl_as_packed_callable!(1; T0);
71impl_as_packed_callable!(2; T0, T1);
72impl_as_packed_callable!(3; T0, T1, T2);
73impl_as_packed_callable!(4; T0, T1, T2, T3);
74impl_as_packed_callable!(5; T0, T1, T2, T3, T4);
75impl_as_packed_callable!(6; T0, T1, T2, T3, T4, T5);
76impl_as_packed_callable!(7; T0, T1, T2, T3, T4, T5, T6);
77impl_as_packed_callable!(8; T0, T1, T2, T3, T4, T5, T6, T7);
78
79pub trait IntoArgHolder {
86 type Target;
87 fn into_arg_holder(self) -> Self::Target;
88}
89
90crate::impl_into_arg_holder_default!(
91 bool, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, f32, f64, String, Bytes
92);
93
94impl IntoArgHolder for &str {
96 type Target = String;
97 fn into_arg_holder(self) -> Self::Target {
98 String::from(self)
99 }
100}
101
102impl IntoArgHolder for &[u8] {
104 type Target = Bytes;
105 fn into_arg_holder(self) -> Self::Target {
106 Bytes::from(self)
107 }
108}
109
110pub trait IntoArgHolderTuple {
112 type Target;
113 fn into_arg_holder_tuple(self) -> Self::Target;
114}
115
116macro_rules! impl_into_arg_holder_tuple {
117 ( $($T:ident),* ; $($idx:tt),* ) => {
118 impl<$($T),*> $crate::function_internal::IntoArgHolderTuple for ($($T,)*)
119 where
120 $($T: IntoArgHolder),* {
121 type Target = ($($T::Target,)*);
122
123 fn into_arg_holder_tuple(self) -> Self::Target {
124 ($(self.$idx.into_arg_holder(),)*)
125 }
126 }
127 };
128}
129
130impl_into_arg_holder_tuple!(;);
131impl_into_arg_holder_tuple!(T0; 0);
132impl_into_arg_holder_tuple!(T0, T1; 0, 1);
133impl_into_arg_holder_tuple!(T0, T1, T2; 0, 1, 2);
134impl_into_arg_holder_tuple!(T0, T1, T2, T3; 0, 1, 2, 3);
135impl_into_arg_holder_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4);
136impl_into_arg_holder_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5);
137impl_into_arg_holder_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6);
138impl_into_arg_holder_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7);
139
140pub trait ArgIntoRef {
147 type Target;
148 fn to_ref(&self) -> &Self::Target;
149}
150
151crate::impl_arg_into_ref!(
152 bool, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, f32, f64, String, Bytes
153);
154
155pub trait TupleAsPackedArgs {
161 const LEN: usize;
162 fn fill_any_view<'a>(&'a self, any_view: &mut [AnyView<'a>]);
163}
164
165macro_rules! impl_tuple_as_packed_args {
166 ( $len:expr; $($T:ident),* ; $($idx:tt),* ) => {
167 impl<$($T),*> TupleAsPackedArgs for ($($T,)*)
168 where
169 $(
170 $T: ArgIntoRef,
171 $T::Target: AnyCompatible,
172 )*
173 {
174 const LEN: usize = $len;
175
176 fn fill_any_view<'a>(&'a self, _any_view: &mut [AnyView<'a>]) {
177 $(
178 _any_view[$idx] = AnyView::from(self.$idx.to_ref());
179 )*
180 }
181 }
182 };
183}
184
185impl_tuple_as_packed_args!(0;;);
186impl_tuple_as_packed_args!(1; T0; 0);
187impl_tuple_as_packed_args!(2; T0, T1; 0, 1);
188impl_tuple_as_packed_args!(3; T0, T1, T2; 0, 1, 2);
189impl_tuple_as_packed_args!(4; T0, T1, T2, T3; 0, 1, 2, 3);
190impl_tuple_as_packed_args!(5; T0, T1, T2, T3, T4; 0, 1, 2, 3, 4);
191impl_tuple_as_packed_args!(6; T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5);
192impl_tuple_as_packed_args!(7; T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6);
193impl_tuple_as_packed_args!(8; T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7);