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}