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
| Pattern | Use | Why |
|---|---|---|
OwnedProtect | raw SEXP, no Rust view | one-shot protect/unprotect on a single SEXP |
ProtectScope + Root | several SEXPs in one function body | batched UNPROTECT, no Rust view |
Protected<'a, T> | SEXP + Rust view of its data | pairs 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>
impl<'a, T> Protected<'a, T>
Sourcepub unsafe fn new(sexp: SEXP, inner: T) -> Self
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.
sexpmust be a valid SEXP.- Borrowed data in
innermust remain valid for its declared lifetime; this guard alone cannot guarantee that whenTexposes 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)
}Sourcepub unsafe fn from_trusted(_sexp: SEXP, inner: T) -> Self
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.
sexpmust be a valid SEXP.sexpmust remain GC-protected for the lifetime of the returnedProtected.- Lifetime contract same as
Protected::new.
Sourcepub fn into_inner(self) -> T
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§
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> 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: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.