1#![warn(missing_docs)]
31
32use libR_sys::{SEXPTYPE::*, *};
33
34use protect::{BoxProtected, Protected};
35
36pub use libR_sys;
37pub use libR_sys::SEXP;
38use sexp::{
39 env::{Env, Symbol},
40 function::{Builtin, Closure, Function},
41 lang::{Lang, PairlistBuilder},
42 matrix::Matrix,
43 vector::{CharacterVector, IntegerVector, List, LogicalVector, RealVector},
44};
45
46pub(crate) mod debug;
47#[cfg(feature = "embedded")]
48pub mod embedded;
49pub mod message;
50pub mod prelude;
51pub mod protect;
52pub mod sexp;
53
54#[allow(missing_docs)]
56#[derive(Debug)]
57pub enum AnySexp<T: JustSEXP> {
58 Nil(T),
59 Logical(LogicalVector<T>),
60 LogicalMatrix(Matrix<LogicalVector<T>>),
61 Real(RealVector<T>),
62 RealMatrix(Matrix<RealVector<T>>),
63 Integer(IntegerVector<T>),
64 IntegerMatrix(Matrix<IntegerVector<T>>),
65 Character(CharacterVector<T>),
66 CharacterMatrix(Matrix<CharacterVector<T>>),
67 List(List<T>),
68 Symbol(Symbol<T>),
69 Lang(Lang<T>),
70 Function(Function<T>),
71 Builtin(Builtin<T>),
72 Closure(Closure<T>),
73 Environment(Env<T>),
74 Other(T),
75}
76
77impl<T: JustSEXP> From<T> for AnySexp<T> {
78 fn from(value: T) -> Self {
79 let sexp = value.get_sexp();
80 match unsafe { TYPEOF(sexp) } {
81 NILSXP => AnySexp::Nil(value),
82 LGLSXP => Matrix::wrap_sexp(sexp)
83 .map(AnySexp::LogicalMatrix)
84 .unwrap_or_else(|| {
85 AnySexp::Logical(unsafe { LogicalVector::wrap_sexp_unchecked(sexp) })
86 }),
87 REALSXP => Matrix::wrap_sexp(sexp)
88 .map(AnySexp::RealMatrix)
89 .unwrap_or_else(|| AnySexp::Real(unsafe { RealVector::wrap_sexp_unchecked(sexp) })),
90 INTSXP => Matrix::wrap_sexp(sexp)
91 .map(AnySexp::IntegerMatrix)
92 .unwrap_or_else(|| {
93 AnySexp::Integer(unsafe { IntegerVector::wrap_sexp_unchecked(sexp) })
94 }),
95 STRSXP => Matrix::wrap_sexp(sexp)
96 .map(AnySexp::CharacterMatrix)
97 .unwrap_or_else(|| {
98 AnySexp::Character(unsafe { CharacterVector::wrap_sexp_unchecked(sexp) })
99 }),
100 SYMSXP => AnySexp::Symbol(unsafe { Symbol::wrap_sexp_unchecked(sexp) }),
101 LANGSXP => AnySexp::Lang(unsafe { Lang::wrap_sexp_unchecked(sexp) }),
102 ENVSXP => AnySexp::Environment(unsafe { Env::wrap_sexp_unchecked(sexp) }),
103 FUNSXP => AnySexp::Function(unsafe { Function::wrap_sexp_unchecked(sexp) }),
104 VECSXP => AnySexp::List(unsafe { List::wrap_sexp_unchecked(sexp) }),
105 _ => {
106 if let Some(builtin) = Builtin::<T>::wrap_sexp(sexp) {
107 AnySexp::Builtin(builtin)
108 } else if let Some(closure) = Closure::<T>::wrap_sexp(sexp) {
109 AnySexp::Closure(closure)
110 } else {
111 AnySexp::Other(value)
112 }
113 }
114 }
115 }
116}
117
118impl<T: JustSEXP> AnySexp<T> {
119 pub fn into_inner(self) -> T {
121 match self {
122 AnySexp::Nil(value) => value,
123 AnySexp::Logical(value) => value.upcast(),
124 AnySexp::LogicalMatrix(value) => value.upcast(),
125 AnySexp::Real(value) => value.upcast(),
126 AnySexp::RealMatrix(value) => value.upcast(),
127 AnySexp::Integer(value) => value.upcast(),
128 AnySexp::IntegerMatrix(value) => value.upcast(),
129 AnySexp::Character(value) => value.upcast(),
130 AnySexp::CharacterMatrix(value) => value.upcast(),
131 AnySexp::Symbol(value) => value.upcast(),
132 AnySexp::Lang(value) => value.upcast(),
133 AnySexp::Function(value) => value.upcast(),
134 AnySexp::Builtin(value) => value.upcast(),
135 AnySexp::Closure(value) => value.upcast(),
136 AnySexp::Environment(value) => value.upcast(),
137 AnySexp::List(value) => value.upcast(),
138 AnySexp::Other(value) => value,
139 }
140 }
141 pub fn inner_ref(&self) -> &T {
143 match self {
144 AnySexp::Nil(value) => value,
145 AnySexp::Logical(value) => value.inner_ref(),
146 AnySexp::LogicalMatrix(value) => value.inner_ref(),
147 AnySexp::Real(value) => value.inner_ref(),
148 AnySexp::RealMatrix(value) => value.inner_ref(),
149 AnySexp::Integer(value) => value.inner_ref(),
150 AnySexp::IntegerMatrix(value) => value.inner_ref(),
151 AnySexp::Character(value) => value.inner_ref(),
152 AnySexp::CharacterMatrix(value) => value.inner_ref(),
153 AnySexp::Symbol(value) => value.inner_ref(),
154 AnySexp::Lang(value) => value.inner_ref(),
155 AnySexp::Function(value) => value.inner_ref(),
156 AnySexp::Builtin(value) => value.inner_ref(),
157 AnySexp::Closure(value) => value.inner_ref(),
158 AnySexp::Environment(value) => value.inner_ref(),
159 AnySexp::List(value) => value.inner_ref(),
160 AnySexp::Other(value) => value,
161 }
162 }
163}
164impl<T: JustSEXP> HasSEXP for AnySexp<T> {
165 fn get_sexp(&self) -> SEXP {
166 match self {
167 AnySexp::Nil(value) => value.get_sexp(),
168 AnySexp::Logical(value) => value.get_sexp(),
169 AnySexp::LogicalMatrix(value) => value.get_sexp(),
170 AnySexp::Real(value) => value.get_sexp(),
171 AnySexp::RealMatrix(value) => value.get_sexp(),
172 AnySexp::Integer(value) => value.get_sexp(),
173 AnySexp::IntegerMatrix(value) => value.get_sexp(),
174 AnySexp::Character(value) => value.get_sexp(),
175 AnySexp::CharacterMatrix(value) => value.get_sexp(),
176 AnySexp::Symbol(value) => value.get_sexp(),
177 AnySexp::Lang(value) => value.get_sexp(),
178 AnySexp::Function(value) => value.get_sexp(),
179 AnySexp::Builtin(value) => value.get_sexp(),
180 AnySexp::Closure(value) => value.get_sexp(),
181 AnySexp::Environment(value) => value.get_sexp(),
182 AnySexp::List(value) => value.get_sexp(),
183 AnySexp::Other(value) => value.get_sexp(),
184 }
185 }
186}
187
188pub fn null() -> SEXP {
190 unsafe { R_NilValue }
191}
192
193pub trait TypedSEXP: HasSEXP {
195 const SEXP_TYPE: SEXPTYPE;
197}
198
199pub trait HasSEXP {
201 fn get_sexp(&self) -> SEXP;
203
204 fn is_sexp_null(&self) -> bool {
206 unsafe { self.get_sexp() == libR_sys::R_NilValue }
207 }
208
209 fn sexp_type(&self) -> SEXPTYPE {
211 unsafe { TYPEOF(self.get_sexp()) }
212 }
213
214 fn r_print(&self) {
216 unsafe {
217 Rf_PrintValue(self.get_sexp());
218 }
219 }
220
221 fn attrib(&self, tag: SEXP) -> SEXP {
223 unsafe { Rf_getAttrib(self.get_sexp(), tag) }
224 }
225
226 fn coerce(&self, sexp_type: SEXPTYPE) -> SEXP {
228 unsafe { Rf_coerceVector(self.get_sexp(), sexp_type) }
229 }
230
231 fn protect(self) -> Protected<Self>
233 where
234 Self: Sized,
235 {
236 Protected::new(self)
237 }
238
239 fn protect_box(self) -> BoxProtected<Self>
241 where
242 Self: Sized,
243 {
244 BoxProtected::new(self)
245 }
246
247 fn downcast_to<T: HasSEXP>(self) -> Option<T>
249 where
250 Self: DowncastSEXP<T>,
251 {
252 self.downcast()
253 }
254}
255
256impl HasSEXP for SEXP {
257 fn get_sexp(&self) -> SEXP {
258 *self
259 }
260}
261
262pub trait IndexableSEXP: HasSEXP {
264 type Index;
266 type Output;
268 #[must_use]
269 fn len(&self) -> usize;
271 fn check_inbound(&self, index: usize) {
273 if index >= self.len() {
274 panic!(
275 "index out of bounds: the len is {} but the index is {}",
276 self.len(),
277 index
278 );
279 }
280 }
281
282 fn get_elt(&self, index: Self::Index) -> Self::Output;
284 fn set_elt(&mut self, index: Self::Index, value: impl Into<Self::Output>);
286}
287
288pub unsafe trait JustSEXP: HasSEXP + Sized {
300 type Inner: JustSEXP;
302 unsafe fn transmute_to<U: JustSEXP>(self) -> U {
308 let sexp = self.get_sexp();
309 std::mem::forget(self);
310 U::wrap_sexp_unchecked(sexp)
311 }
312
313 fn wrap_sexp(sexp: SEXP) -> Option<Self> {
315 Some(unsafe { Self::wrap_sexp_unchecked(sexp) })
316 }
317
318 unsafe fn wrap_sexp_unchecked(sexp: SEXP) -> Self;
320
321 fn upcast(self) -> Self::Inner;
323
324 fn inner_ref(&self) -> &Self::Inner;
326}
327
328unsafe impl JustSEXP for SEXP {
329 type Inner = SEXP;
330
331 fn upcast(self) -> Self::Inner {
332 self
333 }
334
335 unsafe fn wrap_sexp_unchecked(sexp: SEXP) -> Self {
336 sexp
337 }
338
339 fn inner_ref(&self) -> &Self::Inner {
340 self
341 }
342}
343
344pub unsafe trait ProtectedSEXP: HasSEXP {
346 type Inner: HasSEXP;
348
349 fn forget(self) -> Self::Inner;
351
352 fn unprotect(self) -> Self::Inner;
354
355 fn build_pairlist(self) -> PairlistBuilder<Self>
357 where
358 Self: Sized,
359 Self::Inner: JustSEXP,
360 {
361 PairlistBuilder::new(self)
362 }
363}
364
365pub trait DowncastSEXP<T: HasSEXP>: HasSEXP + Sized {
370 fn downcast(self) -> Option<T>;
372}
373
374impl<T: HasSEXP> DowncastSEXP<T> for T {
375 fn downcast(self) -> Option<T> {
376 Some(self)
377 }
378}