Skip to content

Commit d68ff08

Browse files
committed
Add get() and check_length() to Varrags
1 parent 7efa566 commit d68ff08

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

gdnative-core/src/export/method.rs

+69
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,75 @@ impl<'a> Varargs<'a> {
285285
let args = std::mem::transmute::<&[*mut sys::godot_variant], &[&Variant]>(args);
286286
Self { idx: 0, args }
287287
}
288+
289+
/// Check the length of arguments.
290+
/// See `get()`, `get_opt()` or `get_rest()` for examples.
291+
///
292+
/// # Errors
293+
/// Returns an error if the length of arguments is outside the specified range.
294+
#[inline]
295+
pub fn check_length(&self, bounds: impl ArgumentBounds) -> Result<(), ArgumentLengthError> {
296+
let passed = self.args.len();
297+
if bounds.contains(&passed) {
298+
Ok(())
299+
} else {
300+
Err(ArgumentLengthError::new(passed, bounds))
301+
}
302+
}
303+
304+
/// Returns the type-converted value at the specified argument position.
305+
///
306+
/// # Errors
307+
/// Returns an error if the conversion fails or the argument is not set.
308+
///
309+
/// # Examples
310+
/// ```
311+
/// # fn call(args: gdnative::export::Varargs) -> Result<(), Box<dyn std::error::Error>> {
312+
/// args.check_length(2)?;
313+
/// let a: usize = args.get(0)?;
314+
/// let rest: i64 = args.get(1)?;
315+
/// # Ok(())
316+
/// # }
317+
/// ```
318+
#[inline]
319+
pub fn get<T: FromVariant>(&self, index: usize) -> Result<T, ArgumentTypeError> {
320+
match self.args.get(index) {
321+
Some(v) => match T::from_variant(v) {
322+
Ok(ok) => Ok(ok),
323+
Err(err) => Err(ArgumentTypeError::new(index, err)),
324+
},
325+
None => {
326+
let err = FromVariantError::Custom("Argument is not set".to_owned());
327+
Err(ArgumentTypeError::new(index, err))
328+
}
329+
}
330+
}
331+
332+
/// Returns the type-converted value at the specified argument position.
333+
/// Returns `None` if the argument is not set.
334+
///
335+
/// # Errors
336+
/// Returns an error if the conversion fails.
337+
///
338+
/// # Examples
339+
/// ```
340+
/// # fn call(args: gdnative::export::Varargs) -> Result<(), Box<dyn std::error::Error>> {
341+
/// args.check_length(1..=2)?;
342+
/// let a: usize = args.get(0)?;
343+
/// let rest: i64 = args.get_opt(1)?.unwrap_or(72);
344+
/// # Ok(())
345+
/// # }
346+
/// ```
347+
#[inline]
348+
pub fn get_opt<T: FromVariant>(&self, index: usize) -> Result<Option<T>, ArgumentTypeError> {
349+
match self.args.get(index) {
350+
Some(v) => match T::from_variant(v) {
351+
Ok(ok) => Ok(Some(ok)),
352+
Err(err) => Err(ArgumentTypeError::new(index, err)),
353+
},
354+
None => Ok(None),
355+
}
356+
}
288357
}
289358

290359
impl<'a> Iterator for Varargs<'a> {

0 commit comments

Comments
 (0)