rustr/traits/
attr.rs

1use ::rdll::*;
2use traits::*;
3use std::ffi::{CString, CStr};
4use storage::*;
5use util::c_str;
6
7use symbol::*;
8
9pub trait RAttribute : ToSEXP{
10    fn get_attr<D: RNew, S: SEXPbucket, EE: Into<SymbolM<S>>>(&self, name: EE) -> RResult<D> {
11        unsafe { D::rnew(Rf_getAttrib(self.s(), name.into().s())) }
12    }
13    fn set_attr<T: ToSEXP, EE: Into<SymbolM<S>>, S: SEXPbucket>(&self, name: EE, attr: T) {
14        unsafe {
15            Rf_setAttrib(self.s(), name.into().s(), attr.s());
16        }
17    }
18    fn attribute_names(&self) -> Vec<CString> {
19        let mut v: Vec<CString> = Vec::new();
20
21        let mut attrs = unsafe { ATTRIB(self.s()) };
22        unsafe {
23            while attrs != R_NilValue {
24                v.push(CStr::from_ptr(R_CHAR(PRINTNAME(TAG(attrs)))).to_owned());
25                attrs = CDR(attrs);
26            }
27            v
28        }
29    }
30    fn has_attribute(&self, attr: &str) -> bool {
31        let mut attrs = unsafe { ATTRIB(self.s()) };
32        unsafe {
33            while attrs != R_NilValue {
34                if c_str(attr) == CStr::from_ptr(R_CHAR(PRINTNAME(TAG(attrs)))).to_owned() {
35                    return true;
36                }
37                attrs = CDR(attrs);
38            }
39        }
40        false
41    }
42    fn attributte<D: RNew>(&self) -> RResult<D> {
43        unsafe { RNew::rnew(ATTRIB(self.s())) }
44    }
45}