rustr/
formula.rs

1//! R Formula type
2//!
3//!
4
5use ::rdll::*;
6use ::storage::*;
7use ::traits::*;
8use ::rtype::*;
9use ::error::*;
10use std::str::FromStr;
11use rcast::*;
12
13use util::*;
14use std::ffi::CString;
15
16pub type RFml = RFmlM<Preserve>;
17
18gen_traits_sexp!(RFmlM);
19
20impl<T: SEXPbucket> FromStr for RFmlM<T> {
21    type Err = RError;
22    fn from_str(string: &str) -> RResult<Self> {
23        let char = CString::new(string)?;
24        let dd = convert_using_rfunction(unsafe { Rf_mkString(char.as_ptr()) }, "as.formula")?;
25        Ok(RFmlM { data: T::new(dd) })
26    }
27}
28
29impl<T: SEXPbucket> RFmlM<T> {
30    pub fn new(x: SEXP) -> RResult<Self> {
31        unsafe {
32
33            let res: SEXP = match RTYPEOF(x) {
34                LANGSXP => {
35                    if Rf_inherits(x, c_str("formula").as_ptr()) == Rboolean::TRUE {
36                        x
37                    } else {
38                        let zz = convert_using_rfunction(x, "as.formula")?;
39                        zz
40                    }
41                }
42                EXPRSXP | VECSXP => {
43                    // lists or expression
44                    if Rf_length(x) > 0 {
45                        let y = VECTOR_ELT(x, 0);
46                        if Rf_inherits(y, c_str("formula").as_ptr()) == Rboolean::TRUE {
47                            y
48                        } else {
49                            let rr = convert_using_rfunction(y, "as.formula")?;
50                            rr
51                        }
52                    } else {
53                        return rraise("cannot create formula from empty list or expression");
54                    }
55                }
56                _ => {
57                    let dd = convert_using_rfunction(x, "as.formula")?;
58                    dd
59                }
60            };
61            Ok(RFmlM { data: T::new(res) })
62        }
63    }
64}
65// impl<T: SEXPbucket> FromCastSEXP for RFmlM<T> {
66//    fn casts(x: SEXP) -> RResult<RLangImpl<T>> {
67//        unsafe { Ok(RLangImpl { data: T::new(Rf_lang1(try!(r_cast(x, LANGSXP)))) }) }
68//    }
69// }
70
71
72impl<T: SEXPbucket> RNew for RFmlM<T> {
73    fn rnew(x: SEXP) -> RResult<Self> {
74        Self::new(x)
75    }
76}