Skip to main content

ProtectedStrVec

Struct ProtectedStrVec 

Source
pub struct ProtectedStrVec {
    inner: StrVec,
    len: isize,
    _protect: Option<OwnedProtect>,
}
Expand description

GC-protected view over an R character vector (STRSXP).

Unlike StrVec (which is Copy and trusts the caller for GC protection), ProtectedStrVec owns an OwnedProtect guard that keeps the STRSXP alive. All borrowed data (&str, iterators) has its lifetime tied to &self, not 'static — preventing use-after-GC bugs at compile time.

§When to use

  • StrVec: for SEXP arguments to .Call (R protects them), or when you manage protection yourself. Lightweight, Copy.
  • ProtectedStrVec: when you allocate or receive an STRSXP and need to keep it alive beyond the immediate scope. Not Copy.

§Example

#[miniextendr]
pub fn count_unique(strings: ProtectedStrVec) -> i32 {
    let unique: HashSet<&str> = strings.iter()
        .filter_map(|s| s)
        .collect();
    unique.len() as i32
}

Fields§

§inner: StrVec§len: isize§_protect: Option<OwnedProtect>

Implementations§

Source§

impl ProtectedStrVec

Source

pub unsafe fn new(sexp: SEXP) -> Self

Create a protected view over an STRSXP.

Calls Rf_protect on the SEXP. Use from_sexp_trusted when the SEXP is already protected (e.g., .Call arguments) to avoid double-protecting.

§Safety
  • sexp must be a valid STRSXP.
  • Must be called from the R main thread.
Source

pub unsafe fn from_sexp_trusted(sexp: SEXP) -> Self

Create a view without adding GC protection.

Use this when the SEXP is already protected by R (e.g., a .Call argument, or in a ProtectScope). Avoids the redundant Rf_protect/Rf_unprotect pair.

The lifetime-bound &str borrows are still enforced — this only skips the protect stack push, not the safety guarantees.

§Safety
  • sexp must be a valid STRSXP.
  • sexp must remain GC-protected for the lifetime of this struct.
  • Must be called from the R main thread.
Source

pub fn len(&self) -> isize

Number of elements.

Source

pub fn is_empty(&self) -> bool

Whether the vector is empty.

Source

pub fn get_str(&self, idx: isize) -> Option<&str>

Get the string at index (zero-copy, lifetime tied to &self).

Returns None for out-of-bounds or NA_character_.

Source

pub fn get_cow(&self, idx: isize) -> Option<Cow<'_, str>>

Get the string at index as Cow<str> (encoding-safe, lifetime tied to &self).

Source

pub fn iter(&self) -> ProtectedStrVecIter<'_>

Iterate over elements as Option<&str> (lifetime tied to &self).

Source

pub fn iter_cow(&self) -> ProtectedStrVecCowIter<'_>

Iterate over elements as Option<Cow<str>> (encoding-safe).

Source

pub fn as_sexp(&self) -> SEXP

Get the underlying SEXP (still protected by this handle).

Source

pub fn as_strvec(&self) -> StrVec

Get the inner StrVec (unprotected copy — caller assumes protection responsibility).

Trait Implementations§

Source§

impl Debug for ProtectedStrVec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> IntoIterator for &'a ProtectedStrVec

Source§

type Item = Option<&'a str>

The type of the elements being iterated over.
Source§

type IntoIter = ProtectedStrVecIter<'a>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl IntoR for ProtectedStrVec

Source§

type Error = Infallible

The error type for fallible conversions. Read more
Source§

fn try_into_sexp(self) -> Result<SEXP, Self::Error>

Try to convert this value to an R SEXP. Read more
Source§

unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error>

Try to convert to SEXP without thread safety checks. Read more
Source§

fn into_sexp(self) -> SEXP

Convert this value to an R SEXP, panicking on error. Read more
Source§

unsafe fn into_sexp_unchecked(self) -> SEXP
where Self: Sized,

Convert to SEXP without thread safety checks, panicking on error. Read more
Source§

impl TryFromSexp for ProtectedStrVec

Source§

type Error = SexpError

The error type returned when conversion fails.
Source§

fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error>

Attempt to convert an R SEXP to this Rust type. Read more
Source§

unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error>

Convert from SEXP without thread safety checks. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> RDebug for T
where T: Debug,

Source§

fn debug_str(&self) -> String

Get a compact debug string representation.
Source§

fn debug_str_pretty(&self) -> String

Get a pretty-printed debug string with indentation.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.