@@ -27,6 +27,7 @@ pub struct Arg<'a> {
2727 variadic : bool ,
2828 default_value : Option < String > ,
2929 zval : Option < & ' a mut Zval > ,
30+ variadic_zvals : Vec < Option < & ' a mut Zval > > ,
3031}
3132
3233impl < ' a > Arg < ' a > {
@@ -45,6 +46,7 @@ impl<'a> Arg<'a> {
4546 variadic : false ,
4647 default_value : None ,
4748 zval : None ,
49+ variadic_zvals : vec ! [ ] ,
4850 }
4951 }
5052
@@ -103,6 +105,18 @@ impl<'a> Arg<'a> {
103105 . and_then ( |zv| T :: from_zval_mut ( zv. dereference_mut ( ) ) )
104106 }
105107
108+ /// Retrice all the variadic values for this Rust argument.
109+ pub fn variadic_vals < T > ( & ' a mut self ) -> Vec < T >
110+ where
111+ T : FromZvalMut < ' a > ,
112+ {
113+ self . variadic_zvals
114+ . iter_mut ( )
115+ . filter_map ( |zv| zv. as_mut ( ) )
116+ . filter_map ( |zv| T :: from_zval_mut ( zv. dereference_mut ( ) ) )
117+ . collect ( )
118+ }
119+
106120 /// Attempts to return a reference to the arguments internal Zval.
107121 ///
108122 /// # Returns
@@ -226,17 +240,27 @@ impl<'a, 'b> ArgParser<'a, 'b> {
226240 let max_num_args = self . args . len ( ) ;
227241 let min_num_args = self . min_num_args . unwrap_or ( max_num_args) ;
228242 let num_args = self . arg_zvals . len ( ) ;
243+ let has_variadic = self . args . last ( ) . map_or ( false , |arg| arg. variadic ) ;
229244
230- if num_args < min_num_args || num_args > max_num_args {
245+ if num_args < min_num_args || ( !has_variadic && num_args > max_num_args) {
231246 // SAFETY: Exported C function is safe, return value is unused and parameters
232247 // are copied.
233248 unsafe { zend_wrong_parameters_count_error ( min_num_args as _ , max_num_args as _ ) } ;
234249 return Err ( Error :: IncorrectArguments ( num_args, min_num_args) ) ;
235250 }
236251
237252 for ( i, arg_zval) in self . arg_zvals . into_iter ( ) . enumerate ( ) {
238- if let Some ( arg) = self . args . get_mut ( i) {
239- arg. zval = arg_zval;
253+ let arg = match self . args . get_mut ( i) {
254+ Some ( arg) => Some ( arg) ,
255+ // Only select the last item if it's variadic
256+ None => self . args . last_mut ( ) . filter ( |arg| arg. variadic ) ,
257+ } ;
258+ if let Some ( arg) = arg {
259+ if arg. variadic {
260+ arg. variadic_zvals . push ( arg_zval) ;
261+ } else {
262+ arg. zval = arg_zval;
263+ }
240264 }
241265 }
242266
0 commit comments