rustr/
symbol.rs

1//! R Symbol type
2//!
3//!
4
5use ::rdll::*;
6use ::storage::*;
7use ::traits::*;
8use ::rtype::*;
9use ::error::*;
10use std::convert::*;
11use std::ffi::*;
12
13use ::util::*;
14
15pub type Symbol = SymbolM<NoProtect>;
16
17impl<T: SEXPbucket> SymbolM<T> {
18    pub fn new<E: ToSEXP>(x: E) -> RResult<SymbolM<T>> {
19        unsafe {
20            let types = RTYPEOF(x.s());
21            match types {
22                SYMSXP => Ok(SymbolM { data: T::new(x.s()) }),
23
24                CHARSXP => Ok(SymbolM { data: (T::new(Rf_installChar(x.s()))) }),
25
26                STRSXP => {
27                    // todo: check that there is at least one element
28                    Ok(SymbolM { data: T::new(Rf_installChar(STRING_ELT(x.s(), 0))) })
29                }
30
31                _ => rraise("cannot convert to symbol (SYMSXP)"),
32            }
33        }
34    }
35
36    pub fn cstring(&self) -> CString {
37        unsafe { CStr::from_ptr(R_CHAR(PRINTNAME(self.data.s()))).to_owned() }
38    }
39}
40
41impl<T: SEXPbucket> From<CString> for SymbolM<T> {
42    fn from(x: CString) -> SymbolM<T> {
43        unsafe { SymbolM { data: T::new(Rf_install(x.as_ptr())) } }
44
45    }
46}
47
48impl<'a, T: SEXPbucket> From<&'a str> for SymbolM<T> {
49    fn from(x: &'a str) -> SymbolM<T> {
50        unsafe { SymbolM { data: T::new(Rf_install(c_str(x).as_ptr())) } }
51    }
52}
53
54impl<T: SEXPbucket> From<String> for SymbolM<T> {
55    fn from(x: String) -> SymbolM<T> {
56        unsafe { SymbolM { data: T::new(Rf_install(c_str(&x).as_ptr())) } }
57    }
58}
59
60impl<T: SEXPbucket> From<SymbolM<T>> for CString {
61    fn from(x: SymbolM<T>) -> CString {
62        unsafe { CStr::from_ptr(R_CHAR(PRINTNAME(x.data.s()))).to_owned() }
63    }
64}
65
66
67gen_traits_sexp!(SymbolM);