1
1
//! Method registration
2
2
3
3
use std:: borrow:: Cow ;
4
+ use std:: convert:: TryFrom ;
4
5
use std:: fmt;
5
6
use std:: marker:: PhantomData ;
6
7
use std:: ops:: Bound ;
@@ -214,6 +215,7 @@ impl<C: NativeClass, F: StaticArgsMethod<C>> Method<C> for StaticArgs<F> {
214
215
pub struct Varargs < ' a > {
215
216
idx : usize ,
216
217
args : & ' a [ & ' a Variant ] ,
218
+ offset_index : usize ,
217
219
}
218
220
219
221
impl < ' a > Varargs < ' a > {
@@ -283,7 +285,11 @@ impl<'a> Varargs<'a> {
283
285
pub unsafe fn from_sys ( num_args : libc:: c_int , args : * mut * mut sys:: godot_variant ) -> Self {
284
286
let args = std:: slice:: from_raw_parts ( args, num_args as usize ) ;
285
287
let args = std:: mem:: transmute :: < & [ * mut sys:: godot_variant ] , & [ & Variant ] > ( args) ;
286
- Self { idx : 0 , args }
288
+ Self {
289
+ idx : 0 ,
290
+ args,
291
+ offset_index : 0 ,
292
+ }
287
293
}
288
294
289
295
/// Check the length of arguments.
@@ -317,14 +323,17 @@ impl<'a> Varargs<'a> {
317
323
/// ```
318
324
#[ inline]
319
325
pub fn get < T : FromVariant > ( & self , index : usize ) -> Result < T , ArgumentTypeError > {
320
- match self . args . get ( index) {
326
+ let relative_index = index;
327
+ let actual_index = index + self . offset_index ;
328
+
329
+ match self . args . get ( relative_index) {
321
330
Some ( v) => match T :: from_variant ( v) {
322
331
Ok ( ok) => Ok ( ok) ,
323
- Err ( err) => Err ( ArgumentTypeError :: new ( index , err) ) ,
332
+ Err ( err) => Err ( ArgumentTypeError :: new ( actual_index , err) ) ,
324
333
} ,
325
334
None => {
326
335
let err = FromVariantError :: Custom ( "Argument is not set" . to_owned ( ) ) ;
327
- Err ( ArgumentTypeError :: new ( index , err) )
336
+ Err ( ArgumentTypeError :: new ( actual_index , err) )
328
337
}
329
338
}
330
339
}
@@ -346,14 +355,52 @@ impl<'a> Varargs<'a> {
346
355
/// ```
347
356
#[ inline]
348
357
pub fn get_opt < T : FromVariant > ( & self , index : usize ) -> Result < Option < T > , ArgumentTypeError > {
349
- match self . args . get ( index) {
358
+ let relative_index = index;
359
+ let actual_index = index + self . offset_index ;
360
+
361
+ match self . args . get ( relative_index) {
350
362
Some ( v) => match T :: from_variant ( v) {
351
363
Ok ( ok) => Ok ( Some ( ok) ) ,
352
- Err ( err) => Err ( ArgumentTypeError :: new ( index , err) ) ,
364
+ Err ( err) => Err ( ArgumentTypeError :: new ( actual_index , err) ) ,
353
365
} ,
354
366
None => Ok ( None ) ,
355
367
}
356
368
}
369
+
370
+ /// Returns the type-converted value from the specified argument position.
371
+ ///
372
+ /// # Errors
373
+ /// Returns an error if the conversion fails.
374
+ ///
375
+ /// # Examples
376
+ /// ```ignore
377
+ /// # fn call(args: gdnative::export::Varargs) -> Result<(), Box<dyn std::error::Error>> {
378
+ /// args.check_length(1..)?;
379
+ /// let a: usize = args.get(0)?;
380
+ /// let rest: Vec<i64> = args.get_rest(1)?;
381
+ /// # Ok(())
382
+ /// # }
383
+ /// ```
384
+ #[ inline]
385
+ pub fn get_rest < T : TryFrom < Varargs < ' a > > > ( & self , rest_index : usize ) -> Result < T , T :: Error > {
386
+ let relative_rest_index = rest_index;
387
+ let actual_rest_index = rest_index + self . offset_index ;
388
+
389
+ let rest = self . args . get ( relative_rest_index..) . unwrap_or_default ( ) ;
390
+ let varargs = Varargs :: < ' a > {
391
+ idx : 0 ,
392
+ args : rest,
393
+ offset_index : actual_rest_index,
394
+ } ;
395
+ T :: try_from ( varargs)
396
+ }
397
+
398
+ /// Get the varargs's offset index.
399
+ #[ inline]
400
+ #[ must_use]
401
+ pub fn offset_index ( & self ) -> usize {
402
+ self . offset_index
403
+ }
357
404
}
358
405
359
406
impl < ' a > Iterator for Varargs < ' a > {
@@ -711,10 +758,11 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
711
758
#[ inline]
712
759
pub fn get ( mut self ) -> Result < T , ArgumentError < ' a > > {
713
760
self . get_optional_internal ( ) . and_then ( |arg| {
761
+ let actual_index = self . args . idx + self . args . offset_index ;
714
762
arg. ok_or ( ArgumentError {
715
763
site : self . site ,
716
764
kind : ArgumentErrorKind :: Missing {
717
- idx : self . args . idx ,
765
+ idx : actual_index ,
718
766
name : self . name ,
719
767
} ,
720
768
} )
@@ -739,13 +787,13 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
739
787
ty,
740
788
..
741
789
} = self ;
742
- let idx = args. idx ;
790
+ let actual_index = args. idx + args . offset_index ;
743
791
744
792
if let Some ( arg) = args. next ( ) {
745
793
T :: from_variant ( arg) . map ( Some ) . map_err ( |err| ArgumentError {
746
794
site : * site,
747
795
kind : ArgumentErrorKind :: CannotConvert {
748
- idx,
796
+ idx : actual_index ,
749
797
name : name. take ( ) ,
750
798
value : arg,
751
799
ty : ty
0 commit comments