extendr_api/wrapper/
primitive.rs

1use super::*;
2
3/// Wrapper for creating primitive objects.
4///
5/// Make a primitive object, or `NULL` if not available
6///
7#[derive(PartialEq, Clone)]
8pub struct Primitive {
9    pub(crate) robj: Robj,
10}
11
12impl Primitive {
13    #[cfg(feature = "non-api")]
14    /// Make a Primitive object from a string.
15    /// ```
16    /// use extendr_api::prelude::*;
17    /// test! {
18    ///     let builtin = r!(Primitive::from_string("+")?);
19    ///     let special = r!(Primitive::from_string("if")?);
20    ///     assert_eq!(builtin.rtype(), Rtype::Builtin);
21    ///     assert_eq!(special.rtype(), Rtype::Special);
22    /// }
23    /// ```
24    pub fn from_string(val: &str) -> Result<Self> {
25        single_threaded(|| unsafe {
26            // Primitives have a special "SYMVALUE" entry in their symbol.
27            let sym = Symbol::from_string(val);
28            let symvalue = Robj::from_sexp(extendr_ffi::SYMVALUE(sym.get()));
29            if symvalue.is_primitive() {
30                Ok(Primitive { robj: symvalue })
31            } else {
32                Err(Error::ExpectedPrimitive(sym.into()))
33            }
34        })
35    }
36
37    // There is currently no way to convert a primitive to a string.
38}
39
40impl std::fmt::Debug for Primitive {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        let s: String = self.robj.deparse().unwrap();
43        write!(f, "{:?}", s)
44    }
45}