Skip to main content

Protected

Struct Protected 

Source
pub struct Protected<'a, T> {
    inner: T,
    _protect: Option<OwnedProtect>,
    _marker: PhantomData<&'a ()>,
}
Expand description

A Rust value (T) bundled with an OwnedProtect guard on an SEXP the value borrows from. The protect releases on drop; the lifetime ties any borrows inside T to &self, so T’s SEXP-internal references can’t outlive the protection.

§When to use Protected<'a, T> vs the alternatives

PatternUseWhy
OwnedProtectraw SEXP, no Rust viewone-shot protect/unprotect on a single SEXP
ProtectScope + Rootseveral SEXPs in one function bodybatched UNPROTECT, no Rust view
Protected<'a, T>SEXP + Rust view of its datapairs a root with T; does not constrain references inside T

§Lifetimes and thread affinity

This generic bundle does not shorten lifetimes inside T. Its callers must avoid exposing an inner borrowed view after the root is released; use a concrete owner with accessors tied to &self (such as ProtectedStrVec) for that guarantee. Option<OwnedProtect> is !Send + !Sync even when its value is None; the trusted constructor does not change those auto-trait properties.

Fields§

§inner: T§_protect: Option<OwnedProtect>§_marker: PhantomData<&'a ()>

Implementations§

Source§

impl<'a, T> Protected<'a, T>

Source

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

Create a protected bundle. Calls Rf_protect on sexp.

inner may borrow from sexp, but this bundle does not rewrite those lifetimes. The caller must ensure any references copied from inner remain valid, including after this root is dropped.

§Safety
  • Must be called from the R main thread.
  • sexp must be a valid SEXP.
  • Borrowed data in inner must remain valid for its declared lifetime; this guard alone cannot guarantee that when T exposes a longer reference (for example, T = &'static str).
§Example
ⓘ
use miniextendr_api::{Protected, OwnedProtect};
use miniextendr_api::prelude::SEXP;

unsafe fn wrap_view(sexp: SEXP, view: MyView<'_>) -> Protected<'_, MyView<'_>> {
    // Protect the SEXP and bundle it with the view.
    // The caller must keep any references exposed by MyView valid.
    Protected::new(sexp, view)
}
Source

pub unsafe fn from_trusted(_sexp: SEXP, inner: T) -> Self

Create a protected bundle without adding to the protect stack.

Use when sexp is already protected by R (a .Call argument, a ProtectScope slot, an enclosing OwnedProtect) to avoid double-protecting. As with new, 'a does not narrow references contained in T.

§Safety
  • Must be called from the R main thread.
  • sexp must be a valid SEXP.
  • sexp must remain GC-protected for the lifetime of the returned Protected.
  • Lifetime contract same as Protected::new.
Source

pub fn get(&self) -> &T

Borrow the inner view.

Source

pub fn into_inner(self) -> T

Consume the bundle and return the inner view.

The OwnedProtect guard drops here, releasing the SEXP from the protect stack. Any owned data extracted from T must not retain SEXP references after this point.

Trait Implementations§

Source§

impl<'a, T: Debug> Debug for Protected<'a, T>

Source§

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

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

impl<'a, T> Deref for Protected<'a, T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &T

Dereferences the value.

Auto Trait Implementations§

§

impl<'a, T> !Send for Protected<'a, T>

§

impl<'a, T> !Sync for Protected<'a, T>

§

impl<'a, T> Freeze for Protected<'a, T>
where T: Freeze,

§

impl<'a, T> RefUnwindSafe for Protected<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Unpin for Protected<'a, T>
where T: Unpin,

§

impl<'a, T> UnsafeUnpin for Protected<'a, T>
where T: UnsafeUnpin,

§

impl<'a, T> UnwindSafe for Protected<'a, T>
where T: UnwindSafe,

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§

#[doc(hidden)]
unsafe extern "C" fn __RDebug_debug_str_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Self: Sized + RDebug,

Method shim for RDebug::debug_str. Read more
Source§

#[doc(hidden)]
unsafe extern "C" fn __RDebug_debug_str_pretty_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Self: Sized + RDebug,

Method shim for RDebug::debug_str_pretty. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

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

Source§

default fn lower_bound(&self) -> usize

🔬This is a nightly-only experimental API. (core_io_internals)
Returns a lower bound on the number of elements this container-like item contains. For example, an array [u8; 12] could return any value between 0 and 12 inclusively as a correct implementation. Read more
Source§

default fn upper_bound(&self) -> Option<usize>

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an upper bound on the number of elements this container-like item contains if it can be determined, otherwise None. Read more
Source§

final fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an estimate for the number of elements this container like type contains. Read more
Source§

impl<T> SizedTypeProperties for T

Source§

#[doc(hidden)]
const SIZE: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGNMENT: Alignment = _

🔬This is a nightly-only experimental API. (ptr_alignment_type)
Source§

#[doc(hidden)]
const IS_ZST: bool = _

🔬This is a nightly-only experimental API. (sized_type_properties)
true if this type requires no storage. false if its size is greater than zero. Read more
Source§

#[doc(hidden)]
const LAYOUT: Layout = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const MAX_SLICE_LEN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
The largest safe length for a [Self]. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.

Layout§

Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.