rustr/
s4.rs

1//! R S4 type
2//!
3//!
4
5
6use ::rdll::*;
7use ::storage::*;
8use ::traits::*;
9
10use ::error::*;
11
12use std::ffi::*;
13
14use ::util::*;
15
16
17pub type S4 = S4M<Preserve>;
18
19impl<T: SEXPbucket> NewRObj for S4M<T> {
20    fn new<E: ToSEXP>(x: E) -> RResult<Self> {
21        unsafe {
22            if Rf_isS4(x.s()) != Rboolean::TRUE {
23                return rraise("not an S4 object");
24            }
25            Ok(S4M { data: T::new(x.s()) })
26        }
27    }
28    unsafe fn unew<E: ToSEXP>(x: E) -> Self {
29        S4M { data: T::new(x.s()) }
30    }
31}
32
33
34impl<T: SEXPbucket> S4M<T> {
35    pub fn from_cstring(x: CString) -> RResult<S4M<T>> {
36        unsafe {
37            let res = S4M { data: T::new(R_do_new_object(R_do_MAKE_CLASS(x.as_ptr()))) };
38            if Rf_inherits(res.data.s(), x.as_ptr()) != Rboolean::TRUE {
39                return rraise(format!("error creating S4 object of class: {:?}", x));
40            }
41            Ok(res)
42        }
43    }
44
45    pub fn is(&self, clazz: CString) -> bool {
46        unsafe { derives_from(Rf_getAttrib(self.data.s(), R_ClassSymbol), clazz) }
47    }
48}
49
50
51gen_traits_sexp!(S4M);