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 ;
@@ -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 > {
@@ -713,10 +764,11 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
713
764
#[ inline]
714
765
pub fn get ( mut self ) -> Result < T , ArgumentError < ' a > > {
715
766
self . get_optional_internal ( ) . and_then ( |arg| {
767
+ let actual_index = self . args . idx + self . args . offset_index ;
716
768
arg. ok_or ( ArgumentError {
717
769
site : self . site ,
718
770
kind : ArgumentErrorKind :: Missing {
719
- idx : self . args . idx ,
771
+ idx : actual_index ,
720
772
name : self . name ,
721
773
} ,
722
774
} )
@@ -741,13 +793,13 @@ impl<'r, 'a, T: FromVariant> ArgBuilder<'r, 'a, T> {
741
793
ty,
742
794
..
743
795
} = self ;
744
- let idx = args. idx ;
796
+ let actual_index = args. idx + args . offset_index ;
745
797
746
798
if let Some ( arg) = args. next ( ) {
747
799
T :: from_variant ( arg) . map ( Some ) . map_err ( |err| ArgumentError {
748
800
site : * site,
749
801
kind : ArgumentErrorKind :: CannotConvert {
750
- idx,
802
+ idx : actual_index ,
751
803
name : name. take ( ) ,
752
804
value : arg,
753
805
ty : ty
0 commit comments