Skip to main content

Quoted

Struct Quoted 

Source
pub struct Quoted<'a> {
    expr: SEXP,
    env: SEXP,
    _arg: PhantomData<&'a SEXP>,
    _not_send: PhantomData<*const ()>,
}
Expand description

An argument passed unevaluated: its expression and the environment it was written in, as base R’s substitute(x) and parent.frame() give them.

Take it as a #[miniextendr] parameter. The generated wrapper keeps the parameter as an R formal and passes if (missing(x)) quote(expr=) else list(substitute(x), parent.frame()), which never forces the argument. See the module docs.

ⓘ
use miniextendr_api::{miniextendr, Quoted, SEXP};

#[miniextendr]
pub fn column_name(col: Quoted) -> Option<String> {
    col.as_name().map(str::to_owned)   // column_name(TIME), column_name("TIME")
}

#[miniextendr]
pub fn evaluate(expr: Quoted) -> SEXP {
    expr.eval()                          // eval(expr, env)
}

parent.frame() is the environment of the function that called the wrapper, which is where the expression was written when the user calls the wrapper directly or through UseMethod(). A wrapper reached through a function that forwards its own argument (g <- function(y) f(y)) receives y and g’s frame, as subset() does. To resolve forwarding, {{ x }} and !!x, take a Quosure.

Fields§

§expr: SEXP§env: SEXP§_arg: PhantomData<&'a SEXP>

Borrows the .Call() argument that roots expr and env.

§_not_send: PhantomData<*const ()>

R objects stay on R’s main thread.

Implementations§

Source§

impl<'a> Quoted<'a>

Source

#[doc(hidden)]
pub unsafe fn from_wrapper_arg(arg: &'a SEXP) -> Option<Self>

Read the argument a generated wrapper passed for a Quoted parameter: None when the argument is missing (quote(expr=)). Generated code calls this; user code has no reason to.

§Panics

When arg is not the wrapper’s list(<expr>, <environment>).

§Safety

R’s main thread; arg stays rooted for 'a.

Source

#[doc(hidden)]
pub unsafe fn missing_from_wrapper_arg(arg: &'a SEXP) -> Missing<Self>

Self::from_wrapper_arg for a Missing<Quoted> parameter.

§Safety

As Self::from_wrapper_arg.

Source

pub fn expr(&self) -> SEXP

The expression as written: a symbol, a call, or a constant (substitute(x)).

Source

pub fn env(&self) -> SEXP

The environment the expression was written in (parent.frame()).

Source

pub fn as_name(&self) -> Option<&'a str>

The name the argument stands for: TIME and "TIME" both give "TIME". None for any other expression (a call, a number, NA).

Source

pub fn eval(&self) -> SEXP

Evaluate the expression in its environment, eval(expr, env), keeping the caller’s condition handlers (eval_with_handlers).

The value is unprotected: protect it before the next allocation.

Source

pub fn eval_in(&self, data: SEXP) -> SEXP

Evaluate the expression with data as a data mask, like eval(expr, data, env): the elements of a list or the columns of a data frame are visible by name, ahead of the expression’s environment. The first of two elements with one name wins, and unnamed elements are not visible. An environment is used as is (env is not consulted), and NULL evaluates in the expression’s environment.

The value is unprotected: protect it before the next allocation.

§Panics

When data is not a list, a data frame, an environment or NULL.

Source

pub fn try_eval_in(&self, data: SEXP) -> Result<SEXP, REvalError>

eval_in with an R error returned as Err, as try_eval_with_handlers returns it: the caller’s handlers still see the expression’s warnings and messages. The mask and the rules for data are eval_in’s.

A subset() method can explain a column that doesn’t exist and leave every other error as R raised it (REvalError::reraise):

ⓘ
let keep = match subset.try_eval_in(table) {
    Ok(keep) => keep,
    // `unknown_column` compares the expression's names with the table's.
    Err(e) if unknown_column(&subset, table) => {
        rust_error!(class = "pkg_unknown_column", "{e}; the columns are ...")
    }
    // SAFETY: inside the `#[miniextendr]` call.
    Err(e) => unsafe { e.reraise() },
};

The value is unprotected: protect it before the next allocation.

§Panics

When data is not a list, a data frame, an environment or NULL.

Source

unsafe fn eval_masked<R>( &self, data: SEXP, eval: unsafe fn(SEXP, SEXP) -> R, ) -> R

Evaluate the expression with data as a mask, as eval_in describes, through eval.

§Safety

As eval’s: R’s main thread, inside a miniextendr boundary; data rooted by the caller.

Auto Trait Implementations§

§

impl<'a> !Send for Quoted<'a>

§

impl<'a> !Sync for Quoted<'a>

§

impl<'a> Freeze for Quoted<'a>

§

impl<'a> RefUnwindSafe for Quoted<'a>

§

impl<'a> Unpin for Quoted<'a>

§

impl<'a> UnsafeUnpin for Quoted<'a>

§

impl<'a> UnwindSafe for Quoted<'a>

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> 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: 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: 16 bytes