rustr/traits/
dim.rs

1use rdll::*;
2use protect::stackp::*;
3use traits::*;
4use error::*;
5use std::ffi::CString;
6use rtype::*;
7
8pub trait RDim: RAttribute+RSize {
9    type Output;
10    fn dim(&self) -> Vec<usize> {
11        if !self.is_matrix() && !self.is_array() {
12            return Vec::new();
13        }
14        unsafe {
15            let res = Shield::new(Rf_getAttrib(self.s(), R_DimSymbol));
16            Vec::urnew(res.s())
17        }
18    }
19    fn set_dim(&mut self, x: &[usize]) -> RResult<()> {
20		if self.rsize() == 0{
21			return rraise("can not set 0 length vector");
22        }
23    	let lens = x.iter().fold(1,|sum,i| sum * i );
24        if self.rsize() as usize != lens {
25			return rraise(format!("length is {} , can not set dimension {:?}",self.rsize(),lens));
26        }
27        unsafe {
28            Rf_setAttrib(self.s(), R_DimSymbol, x.uintor());
29        }
30        Ok(())
31    }
32    fn nrow(&self) -> usize {
33        if !self.is_matrix() {
34            return 0;
35        }
36        self.dim()[0]
37    }
38    fn ncol(&self) -> usize {
39        if !self.is_matrix() {
40            return 0;
41        }
42        self.dim()[1]
43    }
44    fn dimnamec(&self, side: usize) -> Vec<CString> {
45        if !self.is_matrix() && !self.is_array() {
46            return Vec::new();
47        }
48        unsafe {
49            let dims = self.dim();
50            if dims.len() < side {
51                return Vec::new();
52            }
53            let dimnames = Rf_getAttrib(self.s(), R_DimNamesSymbol);
54            if Rf_isNull(dimnames) == Rboolean::TRUE {
55                return Vec::new();
56            }
57            let res = VECTOR_ELT(dimnames, (side - 1) as R_xlen_t);
58            Vec::urnew(res.s())
59        }
60    }
61    fn dimname(&self, side: usize) -> RResult<Vec<String>> {
62        if !self.is_matrix() && !self.is_array() {
63            return Ok(Vec::new());
64        }
65        unsafe {
66            let dims = self.dim();
67            if dims.len() < side {
68                return Ok(Vec::new());
69            }
70            let dimnames = Rf_getAttrib(self.s(), R_DimNamesSymbol);
71            if Rf_isNull(dimnames) == Rboolean::TRUE {
72                return Ok(Vec::new());
73            }
74            let res = VECTOR_ELT(dimnames, (side - 1) as R_xlen_t);
75            Vec::rnew(res.s())
76        }
77    }
78    // CharVec
79    fn set_dimname(&mut self, side: usize, x: &[String]) -> RResult<()> {
80        unsafe {
81            if x.len() == 0 {
82                Rf_setAttrib(self.s(), R_DimNamesSymbol, R_NilValue);
83                Ok(())
84            } else {
85                let dims = self.dim();
86                if dims.len() < side || dims[side - 1] != x.len() {
87                    return rraise(format!("dimension extent is {} the length of names is {}",
88                                          dims.len(),
89                                          x.len()));
90                }
91
92                let dimnames = Rf_getAttrib(self.s(), R_DimNamesSymbol);
93                if Rf_isNull(dimnames) == Rboolean::TRUE {
94                    let new_dimnames = Shield::new(Rf_allocVector(VECSXP, dims.len() as R_xlen_t))
95                                           .s();
96                    SET_VECTOR_ELT(new_dimnames, (side - 1) as R_xlen_t, try!(x.intor()));
97                    Rf_setAttrib(self.s(), R_DimNamesSymbol, new_dimnames);
98                } else {
99                    SET_VECTOR_ELT(dimnames, (side - 1) as R_xlen_t, try!(x.intor()));
100                }
101                Ok(())
102            }
103        }
104    }
105}