aorist_extendr_api/robj/
rinternals.rs1use crate::*;
2use std::os::raw;
3
4impl Robj {
8 pub fn is_null(&self) -> bool {
10 unsafe { Rf_isNull(self.get()) != 0 }
11 }
12
13 pub fn is_symbol(&self) -> bool {
15 unsafe { Rf_isSymbol(self.get()) != 0 }
16 }
17
18 pub fn is_logical(&self) -> bool {
20 unsafe { Rf_isLogical(self.get()) != 0 }
21 }
22
23 pub fn is_real(&self) -> bool {
25 unsafe { Rf_isReal(self.get()) != 0 }
26 }
27
28 pub fn is_complex(&self) -> bool {
30 unsafe { Rf_isComplex(self.get()) != 0 }
31 }
32
33 pub fn is_expression(&self) -> bool {
35 unsafe { Rf_isExpression(self.get()) != 0 }
36 }
37
38 pub fn is_environment(&self) -> bool {
40 unsafe { Rf_isEnvironment(self.get()) != 0 }
41 }
42
43 pub fn is_promise(&self) -> bool {
45 self.sexptype() == PROMSXP
46 }
47
48 pub fn is_string(&self) -> bool {
50 unsafe { Rf_isString(self.get()) != 0 }
51 }
52
53 pub fn is_object(&self) -> bool {
55 unsafe { Rf_isObject(self.get()) != 0 }
56 }
57
58 pub fn get_current_srcref(val: i32) -> Robj {
60 unsafe { new_owned(R_GetCurrentSrcref(val as raw::c_int)) }
61 }
62
63 pub fn get_src_filename(&self) -> Robj {
65 unsafe { new_owned(R_GetSrcFilename(self.get())) }
66 }
67
68 pub fn as_char(&self) -> Robj {
70 unsafe { new_owned(Rf_asChar(self.get())) }
71 }
72
73 pub fn coerce_vector(&self, sexptype: u32) -> Robj {
75 single_threaded(|| unsafe { new_owned(Rf_coerceVector(self.get(), sexptype as SEXPTYPE)) })
76 }
77
78 pub fn pair_to_vector_list(&self) -> Robj {
80 single_threaded(|| unsafe { new_owned(Rf_PairToVectorList(self.get())) })
81 }
82
83 pub fn vector_to_pair_list(&self) -> Robj {
85 single_threaded(|| unsafe { new_owned(Rf_VectorToPairList(self.get())) })
86 }
87
88 pub fn as_character_factor(&self) -> Robj {
90 single_threaded(|| unsafe { new_owned(Rf_asCharacterFactor(self.get())) })
91 }
92
93 pub fn alloc_matrix(sexptype: SEXPTYPE, rows: i32, cols: i32) -> Robj {
95 single_threaded(|| unsafe { new_owned(Rf_allocMatrix(sexptype, rows, cols)) })
96 }
97
98 pub fn duplicate(&self) -> Self {
101 single_threaded(|| unsafe { new_owned(Rf_duplicate(self.get())) })
102 }
103
104 pub fn find_function<K: TryInto<Symbol, Error = Error>>(&self, key: K) -> Result<Robj> {
120 let key: Symbol = key.try_into()?;
121 if !self.is_environment() {
122 return Err(Error::NotFound(key.into()));
123 }
124 unsafe {
141 if let Ok(var) = catch_r_error(|| Rf_findFun(key.get(), self.get())) {
142 Ok(new_owned(var))
143 } else {
144 Err(Error::NotFound(key.into()))
145 }
146 }
147 }
148
149 pub fn find_var<K: TryInto<Symbol, Error = Error>>(&self, key: K) -> Result<Robj> {
168 let key: Symbol = key.try_into()?;
169 if !self.is_environment() {
170 return Err(Error::NotFound(key.into()));
171 }
172 unsafe {
189 if let Ok(var) = catch_r_error(|| Rf_findVar(key.get(), self.get())) {
190 if var != R_UnboundValue {
191 Ok(new_owned(var))
192 } else {
193 Err(Error::NotFound(key.into()))
194 }
195 } else {
196 Err(Error::NotFound(key.into()))
197 }
198 }
199 }
200
201 pub fn eval_promise(&self) -> Result<Robj> {
211 if self.is_promise() {
212 self.as_promise().unwrap().eval()
213 } else {
214 Ok(self.into())
215 }
216 }
217
218 pub fn ncols(&self) -> usize {
220 unsafe { Rf_ncols(self.get()) as usize }
221 }
222
223 pub fn nrows(&self) -> usize {
225 unsafe { Rf_nrows(self.get()) as usize }
226 }
227
228 #[doc(hidden)]
230 pub unsafe fn make_external_ptr<T>(p: *mut T, tag: Robj, prot: Robj) -> Self {
231 new_owned(single_threaded(|| {
232 R_MakeExternalPtr(p as *mut ::std::os::raw::c_void, tag.get(), prot.get())
233 }))
234 }
235
236 #[doc(hidden)]
238 pub unsafe fn external_ptr_addr<T>(&self) -> *mut T {
239 R_ExternalPtrAddr(self.get()) as *mut T
240 }
241
242 #[doc(hidden)]
244 pub unsafe fn external_ptr_tag(&self) -> Self {
245 new_owned(R_ExternalPtrTag(self.get()))
246 }
247
248 #[doc(hidden)]
250 pub unsafe fn external_ptr_protected(&self) -> Self {
251 new_owned(R_ExternalPtrProtected(self.get()))
252 }
253
254 #[doc(hidden)]
255 pub unsafe fn register_c_finalizer(&self, func: R_CFinalizer_t) {
256 single_threaded(|| R_RegisterCFinalizer(self.get(), func));
257 }
258
259 pub fn xlengthgets(&self, new_len: usize) -> Result<Robj> {
262 unsafe {
263 if self.is_vector() {
264 Ok(single_threaded(|| {
265 new_owned(Rf_xlengthgets(self.get(), new_len as R_xlen_t))
266 }))
267 } else {
268 Err(Error::ExpectedVector(self.clone()))
269 }
270 }
271 }
272
273 pub fn alloc_vector(sexptype: u32, len: usize) -> Robj {
275 single_threaded(|| unsafe { new_owned(Rf_allocVector(sexptype, len as R_xlen_t)) })
276 }
277
278 pub fn conformable(a: &Robj, b: &Robj) -> bool {
280 single_threaded(|| unsafe { Rf_conformable(a.get(), b.get()) != 0 })
281 }
282
283 pub fn is_array(&self) -> bool {
285 unsafe { Rf_isArray(self.get()) != 0 }
286 }
287
288 pub fn is_factor(&self) -> bool {
290 unsafe { Rf_isFactor(self.get()) != 0 }
291 }
292
293 pub fn is_frame(&self) -> bool {
295 unsafe { Rf_isFrame(self.get()) != 0 }
296 }
297
298 pub fn is_function(&self) -> bool {
300 unsafe { Rf_isFunction(self.get()) != 0 }
301 }
302
303 pub fn is_integer(&self) -> bool {
305 unsafe { Rf_isInteger(self.get()) != 0 }
306 }
307
308 pub fn is_language(&self) -> bool {
310 unsafe { Rf_isLanguage(self.get()) != 0 }
311 }
312
313 pub fn is_pairlist(&self) -> bool {
315 unsafe { Rf_isList(self.get()) != 0 }
316 }
317
318 pub fn is_matrix(&self) -> bool {
320 unsafe { Rf_isMatrix(self.get()) != 0 }
321 }
322
323 pub fn is_list(&self) -> bool {
325 unsafe { Rf_isNewList(self.get()) != 0 }
326 }
327
328 pub fn is_number(&self) -> bool {
330 unsafe { Rf_isNumber(self.get()) != 0 }
331 }
332
333 pub fn is_primitive(&self) -> bool {
335 unsafe { Rf_isPrimitive(self.get()) != 0 }
336 }
337
338 pub fn is_ts(&self) -> bool {
340 unsafe { Rf_isTs(self.get()) != 0 }
341 }
342
343 pub fn is_user_binop(&self) -> bool {
345 unsafe { Rf_isUserBinop(self.get()) != 0 }
346 }
347
348 pub fn is_valid_string(&self) -> bool {
350 unsafe { Rf_isValidString(self.get()) != 0 }
351 }
352
353 pub fn is_valid_string_f(&self) -> bool {
355 unsafe { Rf_isValidStringF(self.get()) != 0 }
356 }
357
358 pub fn is_vector(&self) -> bool {
360 unsafe { Rf_isVector(self.get()) != 0 }
361 }
362
363 pub fn is_vector_atomic(&self) -> bool {
365 unsafe { Rf_isVectorAtomic(self.get()) != 0 }
366 }
367
368 pub fn is_vector_list(&self) -> bool {
370 unsafe { Rf_isVectorList(self.get()) != 0 }
371 }
372
373 pub fn is_vectorizable(&self) -> bool {
375 unsafe { Rf_isVectorizable(self.get()) != 0 }
376 }
377
378 pub fn is_raw(&self) -> bool {
380 self.rtype() == RType::Raw
381 }
382
383 pub fn is_character(&self) -> bool {
385 self.rtype() == RType::Character
386 }
387
388 #[doc(hidden)]
391 pub fn check_external_ptr(&self, expected_tag: &str) -> bool {
392 if self.sexptype() == libR_sys::EXTPTRSXP {
393 let tag = unsafe { self.external_ptr_tag() };
394 if tag.as_str() == Some(expected_tag) {
395 return true;
396 }
397 }
398 false
399 }
400
401 pub fn is_missing_arg(&self) -> bool {
402 unsafe { self.get() == R_MissingArg }
403 }
404
405 pub fn is_unbound_value(&self) -> bool {
406 unsafe { self.get() == R_UnboundValue }
407 }
408
409 pub fn is_package_env(&self) -> bool {
410 unsafe { R_IsPackageEnv(self.get()) != 0 }
411 }
412
413 pub fn package_env_name(&self) -> Robj {
414 unsafe { new_owned(R_PackageEnvName(self.get())) }
415 }
416
417 pub fn is_namespace_env(&self) -> bool {
418 unsafe { R_IsNamespaceEnv(self.get()) != 0 }
419 }
420
421 pub fn namespace_env_spec(&self) -> Robj {
422 unsafe { new_owned(R_NamespaceEnvSpec(self.get())) }
423 }
424}