pub struct List(SEXP);Expand description
Owned handle to an R list (VECSXP).
§Examples
use miniextendr_api::list::List;
let list = List::from_values(vec![1i32, 2, 3]);
assert_eq!(list.len(), 3);
let first: Option<i32> = list.get_index(0);Tuple Fields§
§0: SEXPImplementations§
Source§impl List
impl List
Sourcepub fn as_data_frame(&self) -> Result<BuiltDataFrame, DataFrameError>
pub fn as_data_frame(&self) -> Result<BuiltDataFrame, DataFrameError>
Promote this named list to a DataFrame.
§Errors
Returns DataFrameError if the list has no names or columns differ in length.
Source§impl List
impl List
Sourcepub fn is_list(self) -> bool
pub fn is_list(self) -> bool
Return true if the underlying SEXP is a list (VECSXP) according to R.
Uses SexpExt::is_list (VECSXP check) — not is_pair_list (LISTSXP).
Sourcepub const unsafe fn from_raw(sexp: SEXP) -> Self
pub const unsafe fn from_raw(sexp: SEXP) -> Self
Wrap an existing VECSXP without additional checks.
§Safety
Caller must ensure sexp is a valid list (VECSXP) that stays rooted
while the List is used: List is a Copy view and roots nothing.
Sourcepub fn get(self, idx: isize) -> Option<SEXP>
pub fn get(self, idx: isize) -> Option<SEXP>
Get raw SEXP element at 0-based index. Returns None if out of bounds.
Sourcepub fn get_index<T>(self, idx: isize) -> Option<T>where
T: TryFromSexp,
pub fn get_index<T>(self, idx: isize) -> Option<T>where
T: TryFromSexp,
Get element at 0-based index and convert to type T.
Returns None if index is out of bounds or conversion fails.
The conversion error is discarded, so T’s TryFromSexp::Error is
unconstrained — any element type works, not only those whose error is
SexpError. Callers that need the error (e.g. to distinguish “missing”
from “wrong type”) should use get and convert directly.
Sourcefn text_names(self) -> impl Iterator<Item = (isize, &'static str)>
fn text_names(self) -> impl Iterator<Item = (isize, &'static str)>
The names this list can be looked up by: (position, name) for each
element whose name is neither NA nor invalid UTF-8, in list order.
Empty names are included. Yields nothing when the list has no names
attribute.
get_named_sexp,
first_duplicate_name, NamedList and
the #[derive(TryFromList)] field lookup all walk the names through
this, so they agree on which names count.
The &strs point into R’s CHARSXP cache; they stay valid while the
list (which roots its names attribute) is reachable.
Sourcepub fn get_named_sexp(self, name: &str) -> Option<SEXP>
pub fn get_named_sexp(self, name: &str) -> Option<SEXP>
Get the raw element SEXP associated with name, without conversion.
Returns the element exactly as stored so callers can convert it with any
TryFromSexp error type — not only those whose error is SexpError.
Returns None when the list has no names attribute or no name matches.
When the name appears more than once, the first element with that name
is returned, as R’s x[["name"]] does.
Sourcepub fn first_duplicate_name(self) -> Option<String>
pub fn first_duplicate_name(self) -> Option<String>
The first name that appears more than once in the list, if any.
An R list may repeat a name (list(a = 1, a = 2)), and a List
argument accepts such a list, as R does. A function that needs each
name to be unique checks for it itself, and words its own error:
use miniextendr_api::{List, miniextendr};
#[miniextendr]
pub fn settings_count(settings: List) -> i32 {
if let Some(name) = settings.first_duplicate_name() {
panic!("`settings` has the name {name:?} more than once; each entry needs a unique name");
}
settings.len() as i32
}Only names that can identify an element are compared: NA and empty
names are skipped (R lets any number of elements go unnamed), and so
are names that are not valid UTF-8. Returns None for a list without
a names attribute.
Source#[doc(hidden)]pub fn __mx_field_positions<const N: usize>(
self,
sorted_fields: [&str; N],
) -> Result<[Option<isize>; N], SexpError>
#[doc(hidden)]pub fn __mx_field_positions<const N: usize>(
self,
sorted_fields: [&str; N],
) -> Result<[Option<isize>; N], SexpError>
Positions of a derived struct’s fields, for the code
#[derive(TryFromList)] generates. Not public API.
sorted_fields holds the struct’s field names in ascending byte
order (the derive sorts them); entry k of the result is the position
of the first element named sorted_fields[k], or None when no
element has that name. One pass over the names, O(n log fields).
A field name that appears more than once is an error
(SexpError::DuplicateName): the struct could only keep one of the
values. Other repeated names are ignored, as names that are not fields
are.
Sourcepub fn get_named<T>(self, name: &str) -> Option<T>where
T: TryFromSexp,
pub fn get_named<T>(self, name: &str) -> Option<T>where
T: TryFromSexp,
Get element by name and convert to type T.
Returns None if name not found or conversion fails.
The conversion error is discarded, so T’s TryFromSexp::Error is
unconstrained. Use get_named_sexp and convert
directly when you need to inspect the conversion failure.
Sourcefn get_attr_opt(self, name: SEXP) -> Option<SEXP>
fn get_attr_opt(self, name: SEXP) -> Option<SEXP>
Get an arbitrary attribute by symbol, returning None for R_NilValue.
Sourcepub fn get_dimnames(self) -> Option<SEXP>
pub fn get_dimnames(self) -> Option<SEXP>
Get the dimnames attribute if present.
Sourcepub fn get_rownames(self) -> Option<SEXP>
pub fn get_rownames(self) -> Option<SEXP>
Get row names from the dimnames attribute.
Sourcepub fn get_colnames(self) -> Option<SEXP>
pub fn get_colnames(self) -> Option<SEXP>
Get column names from the dimnames attribute.
Sourcepub fn get_levels(self) -> Option<SEXP>
pub fn get_levels(self) -> Option<SEXP>
Get the levels attribute if present (for factors).
Sourcepub fn set_names(self, names: SEXP) -> Self
pub fn set_names(self, names: SEXP) -> Self
Set the names attribute; returns the same list for chaining.
Equivalent to R’s SET_NAMES(x, n).
Sourcepub fn set_class(self, class: SEXP) -> Self
pub fn set_class(self, class: SEXP) -> Self
Set the class attribute; returns the same list for chaining.
Equivalent to R’s SET_CLASS(x, n).
Sourcepub fn set_dim(self, dim: SEXP) -> Self
pub fn set_dim(self, dim: SEXP) -> Self
Set the dim attribute; returns the same list for chaining.
Equivalent to R’s SET_DIM(x, n).
Sourcepub fn set_dimnames(self, dimnames: SEXP) -> Self
pub fn set_dimnames(self, dimnames: SEXP) -> Self
Set the dimnames attribute; returns the same list for chaining.
Equivalent to R’s SET_DIMNAMES(x, n).
Sourcepub fn set_levels(self, levels: SEXP) -> Self
pub fn set_levels(self, levels: SEXP) -> Self
Set the levels attribute; returns the same list for chaining.
Equivalent to R’s SET_LEVELS(x, l).
Sourcepub fn set_class_str(self, classes: &[&str]) -> Self
pub fn set_class_str(self, classes: &[&str]) -> Self
Sourcepub fn set_data_frame_class(self) -> Self
pub fn set_data_frame_class(self) -> Self
Set class = "data.frame" using a cached class STRSXP.
Equivalent to set_class_str(&["data.frame"]) but avoids allocation.
Sourcepub fn set_names_str(self, names: &[&str]) -> Self
pub fn set_names_str(self, names: &[&str]) -> Self
Sourcepub fn set_row_names_int(self, n: usize) -> Self
pub fn set_row_names_int(self, n: usize) -> Self
Set row.names for a data.frame using compact integer form.
R internally represents row.names as a compact integer vector
c(NA_integer_, -n) when the row names are just 1:n. This is more
memory-efficient than storing n strings.
§Example
let list = List::from_pairs(vec![
("x", vec![1, 2, 3]),
("y", vec![4, 5, 6]),
])
.set_class_str(&["data.frame"])
.set_row_names_int(3); // Row names: "1", "2", "3"Sourcepub fn set_row_names_str(self, row_names: &[&str]) -> Self
pub fn set_row_names_str(self, row_names: &[&str]) -> Self
Set row.names from a vector of strings.
Use this when you need custom row names. For simple sequential row names
(1, 2, 3, …), use set_row_names_int instead.
§Example
let list = List::from_pairs(vec![
("x", vec![1, 2, 3]),
])
.set_class_str(&["data.frame"])
.set_row_names_str(&["row_a", "row_b", "row_c"]);Sourcepub unsafe fn set_elt(self, idx: isize, child: SEXP)
pub unsafe fn set_elt(self, idx: isize, child: SEXP)
Set an element at the given index, protecting the child during insertion.
This is the safe way to insert a freshly allocated SEXP into a list.
The child is protected for the duration of the SET_VECTOR_ELT call,
ensuring it cannot be garbage collected.
§Safety
- Must be called from the R main thread
childmust be a valid SEXPselfmust be a valid, protected VECSXP
§Panics
Panics if idx is out of bounds.
§Example
let scope = ProtectScope::new();
let list = List::from_raw(scope.alloc_vecsxp(n).into_raw());
for i in 0..n {
let child = Rf_allocVector(REALSXP, 10); // unprotected!
list.set_elt(i, child); // safe: protects child during insertion
}Sourcepub unsafe fn set_elt_unchecked(self, idx: isize, child: SEXP)
pub unsafe fn set_elt_unchecked(self, idx: isize, child: SEXP)
Set an element without protecting the child.
§Safety
In addition to the safety requirements of set_elt:
- The caller must ensure
childis already protected or that no GC can occur between child allocation and this call.
Use this for performance when you know the child is already protected
(e.g., it’s a child of another protected container, or you have an
OwnedProtect guard for it).
Sourcepub unsafe fn set_elt_with<F>(self, idx: isize, f: F)
pub unsafe fn set_elt_with<F>(self, idx: isize, f: F)
Set an element using a callback that produces the child.
The callback is executed within a protection scope, so any allocations it performs are protected until insertion completes.
§Safety
- Must be called from the R main thread
selfmust be a valid, protected VECSXP
§Example
let list = List::from_raw(scope.alloc_vecsxp(n).into_raw());
for i in 0..n {
list.set_elt_with(i, || {
let vec = Rf_allocVector(REALSXP, 10);
fill_vector(vec); // can allocate internally
vec
});
}Source§impl List
impl List
Sourcepub fn from_pairs<N, T>(pairs: Vec<(N, T)>) -> Self
pub fn from_pairs<N, T>(pairs: Vec<(N, T)>) -> Self
Build a list from (name, value) pairs, setting names in one pass.
Sourcepub fn from_values<T: IntoR>(values: Vec<T>) -> Self
pub fn from_values<T: IntoR>(values: Vec<T>) -> Self
Sourcepub fn from_raw_values(values: Vec<SEXP>) -> Self
pub fn from_raw_values(values: Vec<SEXP>) -> Self
Build an unnamed list from pre-converted SEXPs.
§Safety Note
The input SEXPs should already be protected or be children of protected containers. This function protects the list during construction.
Sourcepub fn from_scalars_or_list(elements: &[SEXP]) -> Self
pub fn from_scalars_or_list(elements: &[SEXP]) -> Self
Build an atomic vector from homogeneous length-1 scalar SEXPs.
If all elements are length-1 scalars of the same coalesceable type (INTSXP, REALSXP, LGLSXP, STRSXP), returns that atomic vector. Otherwise returns a VECSXP (generic list).
This is the canonical entry point for both DataFrame::into_data_frame
(column building) and SeqSerializer::end (sequence coalescing).
§Safety Note
The input SEXPs should already be protected or be children of protected containers.
Sourcepub fn from_raw_pairs<N>(pairs: Vec<(N, SEXP)>) -> Self
pub fn from_raw_pairs<N>(pairs: Vec<(N, SEXP)>) -> Self
Build a list from (name, SEXP) pairs (heterogeneous-friendly).
§Safety Note
The input SEXPs should already be protected or be children of protected containers. This function protects the list and names vector during construction.
Sourcepub fn from_raw_pairs_empty() -> Self
pub fn from_raw_pairs_empty() -> Self
Build an empty named-list SEXP (zero elements, names attribute set).
Equivalent to Self::from_raw_pairs(vec![]), but avoids the
Vec<(&str, SEXP)> type annotation that Rust requires at empty-vector
callsites where type inference cannot resolve the element type.
Codegen paths that emit an empty from_raw_pairs call (e.g. unit-variant
partitions in #[derive(DataFrameRow)]) use this helper so that a future
signature change to from_raw_pairs only needs to be updated in one
place.
Trait Implementations§
impl Copy for List
Source§impl IntoR for List
impl IntoR for List
impl TrivialClone for List
Source§impl TryFromSexp for List
A List reads any R list, whatever its names.
impl TryFromSexp for List
A List reads any R list, whatever its names.
Accepts a VECSXP only; anything else is a SexpTypeError. A pairlist
(LISTSXP, such as formals(f) or pairlist(...)) is refused, not
coerced (#1866): the coerced copy would be a new object that nothing
roots, since List is a Copy view, so the first allocation in the
function could free it. The caller converts with as.list(), and the
argument error says so.
Names are not checked: R allows a name to appear more than once
(list(a = 1, a = 2)), and so does List. A function that needs unique
names checks with List::first_duplicate_name.
Source§type Error = SexpTypeError
type Error = SexpTypeError
Source§fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error>
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error>
Source§const NATIVE_BORROW: Option<NativeBorrow> = None
const NATIVE_BORROW: Option<NativeBorrow> = None
Source§const CHARACTER_ONLY: bool = false
const CHARACTER_ONLY: bool = false
NULL, is a character vector or a factor. Read moreSource§#[doc(hidden)]const __MX_EXPECTATION: Option<&'static str> = None
#[doc(hidden)]const __MX_EXPECTATION: Option<&'static str> = None
#[miniextendr] cannot tell from the type as written: the
<expected> of a failed conversion’s '<p>' must be <expected>: .... Read moreSource§unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error>
unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error>
Source§#[doc(hidden)]unsafe fn __mx_try_from_rooted(root: Root<'_>) -> Result<Self, Self::Error>
#[doc(hidden)]unsafe fn __mx_try_from_rooted(root: Root<'_>) -> Result<Self, Self::Error>
Source§#[doc(hidden)]fn __mx_has_na(&self) -> bool
#[doc(hidden)]fn __mx_has_na(&self) -> bool
#[miniextendr(no_na)]
refuses after the conversion. Read moreSource§#[doc(hidden)]fn __mx_input_has_na(&self, input: SEXP) -> bool
#[doc(hidden)]fn __mx_input_has_na(&self, input: SEXP) -> bool
#[miniextendr(no_na)] refuses this converted argument, read
from input (the R value it converted from), when no R guard ran. Read moreSource§#[doc(hidden)]fn __mx_try_from_sexp_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
#[doc(hidden)]fn __mx_try_from_sexp_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
check, an element type’s
TryFromSexpElement::check_sexp,
on the R value that carries an element’s class (#1837). Read moreSource§#[doc(hidden)]unsafe fn __mx_try_from_sexp_unchecked_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
#[doc(hidden)]unsafe fn __mx_try_from_sexp_unchecked_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
Auto Trait Implementations§
impl Freeze for List
impl RefUnwindSafe for List
impl Send for List
impl Sync for List
impl Unpin for List
impl UnsafeUnpin for List
impl UnwindSafe for List
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConsumingFallible for Twhere
T: Clone,
Source§impl<I> OptionInner for I
impl<I> OptionInner for I
Source§const OPTION_NATIVE_BORROW: Option<NativeBorrow> = const OPTION_NATIVE_BORROW: Option<NativeBorrow> =
<Option<I> as TryFromSexp>::NATIVE_BORROW;
const OPTION_NATIVE_BORROW: Option<NativeBorrow> = const OPTION_NATIVE_BORROW: Option<NativeBorrow> = <Option<I> as TryFromSexp>::NATIVE_BORROW;
<Option<Self> as TryFromSexp>::NATIVE_BORROW.Source§const OPTION_CHARACTER_ONLY: bool = const OPTION_CHARACTER_ONLY: bool =
<Option<I> as TryFromSexp>::CHARACTER_ONLY;
const OPTION_CHARACTER_ONLY: bool = const OPTION_CHARACTER_ONLY: bool = <Option<I> as TryFromSexp>::CHARACTER_ONLY;
<Option<Self> as TryFromSexp>::CHARACTER_ONLY.impl<T> Printable for T
Source§impl<T> RCopy for Twhere
T: Copy,
impl<T> RCopy for Twhere
T: Copy,
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 moreSource§impl<I> VecInner for I
impl<I> VecInner for I
Source§const VEC_NATIVE_BORROW: Option<NativeBorrow> = const VEC_NATIVE_BORROW: Option<NativeBorrow> =
<Vec<I> as TryFromSexp>::NATIVE_BORROW;
const VEC_NATIVE_BORROW: Option<NativeBorrow> = const VEC_NATIVE_BORROW: Option<NativeBorrow> = <Vec<I> as TryFromSexp>::NATIVE_BORROW;
<Vec<Self> as TryFromSexp>::NATIVE_BORROW.Source§const VEC_CHARACTER_ONLY: bool = const VEC_CHARACTER_ONLY: bool = <Vec<I> as TryFromSexp>::CHARACTER_ONLY;
const VEC_CHARACTER_ONLY: bool = const VEC_CHARACTER_ONLY: bool = <Vec<I> as TryFromSexp>::CHARACTER_ONLY;
<Vec<Self> as TryFromSexp>::CHARACTER_ONLY.Source§impl<I> VecOptionInner for I
impl<I> VecOptionInner for I
Source§const VEC_OPTION_NATIVE_BORROW: Option<NativeBorrow> = const VEC_OPTION_NATIVE_BORROW: Option<NativeBorrow> =
<Vec<Option<I>> as TryFromSexp>::NATIVE_BORROW;
const VEC_OPTION_NATIVE_BORROW: Option<NativeBorrow> = const VEC_OPTION_NATIVE_BORROW: Option<NativeBorrow> = <Vec<Option<I>> as TryFromSexp>::NATIVE_BORROW;
<Vec<Option<Self>> as TryFromSexp>::NATIVE_BORROW.Source§const VEC_OPTION_CHARACTER_ONLY: bool = const VEC_OPTION_CHARACTER_ONLY: bool =
<Vec<Option<I>> as TryFromSexp>::CHARACTER_ONLY;
const VEC_OPTION_CHARACTER_ONLY: bool = const VEC_OPTION_CHARACTER_ONLY: bool = <Vec<Option<I>> as TryFromSexp>::CHARACTER_ONLY;
<Vec<Option<Self>> as TryFromSexp>::CHARACTER_ONLY.Layout§
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