1
1
//! Method registration
2
2
3
3
use std:: borrow:: Cow ;
4
+ use std:: convert:: TryInto ;
4
5
use std:: fmt;
5
6
use std:: marker:: PhantomData ;
6
7
use std:: ops:: { Bound , RangeBounds } ;
@@ -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,56 @@ 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
+ /// Can be converted to any type that implements TryFrom<Varargs>.
372
+ ///
373
+ /// # Errors
374
+ /// Returns an error if the conversion fails.
375
+ ///
376
+ /// # Examples
377
+ /// ```ignore
378
+ /// # fn foo(args: gdnative::export::Varargs) -> Result<(), Box<dyn std::error::Error>> {
379
+ /// args.check_length(1..)?;
380
+ /// let a: usize = args.get(0)?;
381
+ /// let rest: Vec<i64> = args.get_rest(1)?;
382
+ /// # Ok(())
383
+ /// # }
384
+ /// ```
385
+ #[ inline]
386
+ pub fn get_rest < T > ( & self , rest_index : usize ) -> Result < T , <Varargs < ' a > as TryInto < T > >:: Error >
387
+ where
388
+ Varargs < ' a > : TryInto < T > ,
389
+ {
390
+ let relative_rest_index = rest_index;
391
+ let actual_rest_index = rest_index + self . offset_index ;
392
+
393
+ let rest = self . args . get ( relative_rest_index..) . unwrap_or_default ( ) ;
394
+ let varargs = Varargs :: < ' a > {
395
+ idx : 0 ,
396
+ args : rest,
397
+ offset_index : actual_rest_index,
398
+ } ;
399
+ varargs. try_into ( )
400
+ }
401
+
402
+ /// Get the varargs's offset index.
403
+ #[ inline]
404
+ #[ must_use]
405
+ pub fn offset_index ( & self ) -> usize {
406
+ self . offset_index
407
+ }
357
408
}
358
409
359
410
impl < ' a > Iterator for Varargs < ' a > {
@@ -600,10 +651,11 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
600
651
#[ inline]
601
652
pub fn get ( mut self ) -> Result < T , ArgumentError < ' a > > {
602
653
self . get_optional_internal ( ) . and_then ( |arg| {
654
+ let actual_index = self . args . idx + self . args . offset_index ;
603
655
arg. ok_or ( ArgumentError {
604
656
site : self . site ,
605
657
kind : ArgumentErrorKind :: Missing {
606
- idx : self . args . idx ,
658
+ idx : actual_index ,
607
659
name : self . name ,
608
660
} ,
609
661
} )
@@ -628,13 +680,13 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
628
680
ty,
629
681
..
630
682
} = self ;
631
- let idx = args. idx ;
683
+ let actual_index = args. idx + args . offset_index ;
632
684
633
685
if let Some ( arg) = args. next ( ) {
634
686
T :: from_variant ( arg) . map ( Some ) . map_err ( |err| ArgumentError {
635
687
site : * site,
636
688
kind : ArgumentErrorKind :: CannotConvert {
637
- idx,
689
+ idx : actual_index ,
638
690
name : name. take ( ) ,
639
691
value : arg,
640
692
ty : ty
0 commit comments