pub struct Dots {
pub inner: SEXP,
}Expand description
Rust type representing R’s ... (variadic arguments).
The generated R wrapper captures ... as list(...) and passes it to Rust,
so Dots holds a list SEXP. Use as_list or
try_list to access elements by name or position.
Declare it as a &Dots parameter at any position, one per function:
fn foo(x: i32, rest: &Dots, flag: bool) becomes the R formals
x, ..., flag, and parameters after it are matched by name only in R.
Rust ... (or name: ...) is the same as a trailing &Dots parameter.
Fields§
§inner: SEXPRaw list backing this ... capture.
This is usually a VECSXP built from list(...) by generated wrappers.
Implementations§
Source§impl Dots
impl Dots
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Create an empty Dots (equivalent to no ... arguments).
This is useful when calling R functions from Rust that expect dots arguments but you want to pass nothing.
§Example
#[miniextendr]
pub fn my_constructor(x: Doubles, dots: ...) -> Robj {
// ...
}
// Call from Rust with empty dots:
let result = my_constructor(data, Dots::empty());Sourcepub fn as_list(&self) -> List
pub fn as_list(&self) -> List
Convert to a List without additional validation.
This is a zero-cost conversion since the R wrapper already passes
list(...) to us. Use this when you trust the input or want
maximum performance.
§Safety Note
This is safe because the miniextendr macro always wraps ... in
list(...) on the R side. However, if you’re receiving a SEXP
from another source, use try_list instead.
§Example
#[miniextendr]
pub fn process_dots(dots: ...) -> i32 {
let list = dots.as_list();
list.len() as i32
}Sourcepub fn try_list(&self) -> Result<List, SexpTypeError>
pub fn try_list(&self) -> Result<List, SexpTypeError>
Convert to a List, checking that the underlying SEXP is a list.
Accepts a list (VECSXP) only, as TryFromSexp for List does; a
pairlist is refused (#1866). Use this when inner may not come from a
generated wrapper’s list(...).
Names are not checked: R lets the caller repeat a name in ...
(f(a = 1, a = 2)). To refuse that, check
List::first_duplicate_name; a typed spec refuses
repeated names itself.
§Errors
Returns SexpTypeError if the SEXP is not a list.
§Example
#[miniextendr]
pub fn count_named_dots(dots: ...) -> Result<i32, String> {
let list = dots.try_list().map_err(|e| e.to_string())?;
if let Some(name) = list.first_duplicate_name() {
return Err(format!("argument {name:?} was given more than once"));
}
Ok(list.len() as i32)
}Sourcepub fn len(&self) -> isize
pub fn len(&self) -> isize
Get the number of elements in the dots list.
This is equivalent to dots.as_list().len() but avoids
creating an intermediate List wrapper.
Sourcepub fn typed(&self, spec: TypedListSpec) -> Result<TypedList, TypedListError>
pub fn typed(&self, spec: TypedListSpec) -> Result<TypedList, TypedListError>
Validate the dots against a typed list specification.
This provides structured validation with clear error messages for
functions that expect specific named arguments via ....
§Example
use miniextendr_api::typed_list::{TypedListSpec, TypedEntry, TypeSpec};
#[miniextendr]
pub fn process_args(dots: ...) -> Result<i32, String> {
let spec = TypedListSpec::new(vec![
TypedEntry::required("alpha", TypeSpec::Numeric(Some(4))),
TypedEntry::optional("beta", TypeSpec::List(None)),
]);
let validated = dots.typed(spec).map_err(|e| e.to_string())?;
let alpha: Vec<f64> = validated.get("alpha").map_err(|e| e.to_string())?;
Ok(alpha.len() as i32)
}§Errors
Returns TypedListError if:
- The dots are not a valid list
- A required field is missing
- A field has the wrong type or length
- Extra fields exist when
allow_extra = false
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Dots
impl RefUnwindSafe for Dots
impl Send for Dots
impl Sync for Dots
impl Unpin for Dots
impl UnsafeUnpin for Dots
impl UnwindSafe for Dots
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> RDebug for Twhere
T: Debug,
impl<T> RDebug for Twhere
T: Debug,
Source§impl<T> SizeHint for Twhere
T: ?Sized,
impl<T> SizeHint for Twhere
T: ?Sized,
Source§default fn lower_bound(&self) -> usize
default fn lower_bound(&self) -> usize
core_io_internals)[u8; 12] could return any value between 0 and
12 inclusively as a correct implementation. Read moreSource§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read moreLayout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 8 bytes