aorist_extendr_api/wrapper/
mod.rs1use crate::*;
5use libR_sys::*;
6
7pub mod character;
8pub mod environment;
9pub mod expr;
10pub mod function;
11pub mod lang;
12pub mod list;
13pub mod matrix;
14pub mod nullable;
15pub mod pairlist;
16pub mod primitive;
17pub mod promise;
18pub mod raw;
19pub mod symbol;
20
21pub use character::Character;
22pub use environment::{EnvIter, Environment};
23pub use expr::Expression;
24pub use function::Function;
25pub use lang::Language;
26pub use list::{FromList, List, ListIter};
27pub use matrix::{RArray, RColumn, RMatrix, RMatrix3D};
28pub use nullable::Nullable;
29pub use pairlist::{Pairlist, PairlistIter};
30pub use primitive::Primitive;
31pub use promise::Promise;
32pub use raw::Raw;
33pub use symbol::Symbol;
34
35pub(crate) fn make_symbol(name: &str) -> SEXP {
36 let mut bytes = Vec::with_capacity(name.len() + 1);
37 bytes.extend(name.bytes());
38 bytes.push(0);
39 unsafe { Rf_install(bytes.as_ptr() as *const ::std::os::raw::c_char) }
40}
41
42pub(crate) fn make_vector<T>(sexptype: u32, values: T) -> Robj
43where
44 T: IntoIterator,
45 T::IntoIter: ExactSizeIterator,
46 T::Item: Into<Robj>,
47{
48 single_threaded(|| unsafe {
49 let values = values.into_iter();
50 let sexp = Rf_allocVector(sexptype, values.len() as R_xlen_t);
51 ownership::protect(sexp);
52 for (i, val) in values.enumerate() {
53 SET_VECTOR_ELT(sexp, i as R_xlen_t, val.into().get());
54 }
55 Robj::Owned(sexp)
56 })
57}
58
59macro_rules! make_conversions {
60 ($typename: ident, $errname: ident, $isfunc: ident, $errstr: expr) => {
61 impl<'a> FromRobj<'a> for $typename {
62 fn from_robj(robj: &'a Robj) -> std::result::Result<Self, &'static str> {
63 if let Ok(f) = $typename::try_from(robj.clone()) {
64 Ok(f)
65 } else {
66 Err($errstr)
67 }
68 }
69 }
70
71 impl From<$typename> for Robj {
72 fn from(val: $typename) -> Self {
74 val.robj
75 }
76 }
77
78 impl TryFrom<Robj> for $typename {
79 type Error = crate::Error;
80
81 fn try_from(robj: Robj) -> Result<Self> {
83 if robj.$isfunc() {
84 Ok($typename { robj })
85 } else {
86 Err(Error::$errname(robj))
87 }
88 }
89 }
90
91 impl Deref for $typename {
92 type Target = Robj;
93
94 fn deref(&self) -> &Self::Target {
96 &self.robj
97 }
98 }
99 };
100}
101
102make_conversions!(Pairlist, ExpectedPairlist, is_pairlist, "Not a pairlist");
103make_conversions!(Function, ExpectedFunction, is_function, "Not a function");
104make_conversions!(Raw, ExpectedRaw, is_raw, "Not a raw object");
105
106make_conversions!(
107 Character,
108 ExpectedCharacter,
109 is_character,
110 "Not a character object"
111);
112
113make_conversions!(
114 Environment,
115 ExpectedEnvironment,
116 is_environment,
117 "Not an Environment"
118);
119
120make_conversions!(List, ExpectedList, is_list, "Not a List");
121
122make_conversions!(
123 Expression,
124 ExpectedExpression,
125 is_expression,
126 "Not an Expression"
127);
128
129make_conversions!(
130 Language,
131 ExpectedLanguage,
132 is_language,
133 "Not a Language object"
134);
135
136make_conversions!(Symbol, ExpectedSymbol, is_symbol, "Not a Symbol object");
137
138make_conversions!(
139 Primitive,
140 ExpectedPrimitive,
141 is_primitive,
142 "Not a Primitive object"
143);
144
145make_conversions!(Promise, ExpectedPromise, is_promise, "Not a Promise object");
146
147impl Robj {
148 pub fn as_symbol(&self) -> Option<Symbol> {
157 Symbol::try_from(self.clone()).ok()
158 }
159
160 pub fn as_character(&self) -> Option<Character> {
169 Character::try_from(self.clone()).ok()
170 }
171
172 pub fn as_raw(&self) -> Option<Raw> {
182 Raw::try_from(self.clone()).ok()
183 }
184
185 pub fn as_language(&self) -> Option<Language> {
196 Language::try_from(self.clone()).ok()
197 }
198
199 pub fn as_pairlist(&self) -> Option<Pairlist> {
210 Pairlist::try_from(self.clone()).ok()
211 }
212
213 pub fn as_list(&self) -> Option<List> {
223 List::try_from(self.clone()).ok()
224 }
225
226 pub fn as_expression(&self) -> Option<Expression> {
237 Expression::try_from(self.clone()).ok()
238 }
239
240 pub fn as_environment(&self) -> Option<Environment> {
253 Environment::try_from(self.clone()).ok()
254 }
255
256 pub fn as_function(&self) -> Option<Function> {
265 Function::try_from(self.clone()).ok()
266 }
267
268 pub fn as_promise(&self) -> Option<Promise> {
270 Promise::try_from(self.clone()).ok()
271 }
272}
273
274pub trait SymPair {
275 fn sym_pair(self) -> (Option<Robj>, Robj);
276}
277
278impl<S, R> SymPair for (S, R)
279where
280 S: AsRef<str>,
281 R: Into<Robj>,
282{
283 fn sym_pair(self) -> (Option<Robj>, Robj) {
284 let val = self.0.as_ref();
285 let nm = if val.is_empty() {
287 None
288 } else {
289 Some(r!(Symbol::from_string(val)))
290 };
291 (nm, self.1.into())
292 }
293}
294
295impl<S, R> SymPair for &(S, R)
296where
297 S: AsRef<str>,
298 R: Into<Robj>,
299 R: Clone,
300{
301 fn sym_pair(self) -> (Option<Robj>, Robj) {
302 let val = self.0.as_ref();
303 let nm = if val.is_empty() {
304 None
305 } else {
306 Some(r!(Symbol::from_string(val)))
307 };
308 (nm, self.1.clone().into())
309 }
310}