miniextendr_api/from_r/
references.rs1use crate::ffi::{RLogical, RNativeType, SEXP, SEXPTYPE, SexpExt};
10use crate::from_r::{SexpError, SexpLengthError, SexpTypeError, TryFromSexp};
11
12macro_rules! impl_ref_conversions_for {
13 ($t:ty) => {
14 impl TryFromSexp for &'static $t {
15 type Error = SexpError;
16
17 #[inline]
18 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
19 let actual = sexp.type_of();
20 if actual != <$t as RNativeType>::SEXP_TYPE {
21 return Err(SexpTypeError {
22 expected: <$t as RNativeType>::SEXP_TYPE,
23 actual,
24 }
25 .into());
26 }
27 let len = sexp.len();
28 if len != 1 {
29 return Err(SexpLengthError {
30 expected: 1,
31 actual: len,
32 }
33 .into());
34 }
35 unsafe { sexp.as_slice::<$t>() }
36 .first()
37 .ok_or_else(|| SexpLengthError { expected: 1, actual: 0 }.into())
38 }
39
40 #[inline]
41 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
42 let actual = sexp.type_of();
43 if actual != <$t as RNativeType>::SEXP_TYPE {
44 return Err(SexpTypeError {
45 expected: <$t as RNativeType>::SEXP_TYPE,
46 actual,
47 }
48 .into());
49 }
50 let len = unsafe { sexp.len_unchecked() };
51 if len != 1 {
52 return Err(SexpLengthError {
53 expected: 1,
54 actual: len,
55 }
56 .into());
57 }
58 unsafe { sexp.as_slice_unchecked::<$t>() }
59 .first()
60 .ok_or_else(|| SexpLengthError { expected: 1, actual: 0 }.into())
61 }
62 }
63
64 impl TryFromSexp for &'static mut $t {
70 type Error = SexpError;
71
72 #[inline]
73 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
74 let actual = sexp.type_of();
75 if actual != <$t as RNativeType>::SEXP_TYPE {
76 return Err(SexpTypeError {
77 expected: <$t as RNativeType>::SEXP_TYPE,
78 actual,
79 }
80 .into());
81 }
82 let len = sexp.len();
83 if len != 1 {
84 return Err(SexpLengthError {
85 expected: 1,
86 actual: len,
87 }
88 .into());
89 }
90 let ptr = unsafe { <$t as RNativeType>::dataptr_mut(sexp) };
91 Ok(unsafe { &mut *ptr })
92 }
93
94 #[inline]
95 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
96 let actual = sexp.type_of();
97 if actual != <$t as RNativeType>::SEXP_TYPE {
98 return Err(SexpTypeError {
99 expected: <$t as RNativeType>::SEXP_TYPE,
100 actual,
101 }
102 .into());
103 }
104 let len = unsafe { sexp.len_unchecked() };
105 if len != 1 {
106 return Err(SexpLengthError {
107 expected: 1,
108 actual: len,
109 }
110 .into());
111 }
112 let ptr = unsafe { <$t as RNativeType>::dataptr_mut(sexp) };
113 Ok(unsafe { &mut *ptr })
114 }
115 }
116
117 impl TryFromSexp for Option<&'static $t> {
118 type Error = SexpError;
119
120 #[inline]
121 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
122 if sexp.type_of() == SEXPTYPE::NILSXP {
123 return Ok(None);
124 }
125 let value: &'static $t = TryFromSexp::try_from_sexp(sexp)?;
126 Ok(Some(value))
127 }
128
129 #[inline]
130 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
131 if sexp.type_of() == SEXPTYPE::NILSXP {
132 return Ok(None);
133 }
134 let value: &'static $t = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
135 Ok(Some(value))
136 }
137 }
138
139 impl TryFromSexp for Option<&'static mut $t> {
140 type Error = SexpError;
141
142 #[inline]
143 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
144 if sexp.type_of() == SEXPTYPE::NILSXP {
145 return Ok(None);
146 }
147 let value: &'static mut $t = TryFromSexp::try_from_sexp(sexp)?;
148 Ok(Some(value))
149 }
150
151 #[inline]
152 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
153 if sexp.type_of() == SEXPTYPE::NILSXP {
154 return Ok(None);
155 }
156 let value: &'static mut $t =
157 unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
158 Ok(Some(value))
159 }
160 }
161
162 impl TryFromSexp for Vec<&'static $t> {
165 type Error = SexpError;
166
167 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
168 let actual = sexp.type_of();
169 if actual != SEXPTYPE::VECSXP {
170 return Err(SexpTypeError {
171 expected: SEXPTYPE::VECSXP,
172 actual,
173 }
174 .into());
175 }
176
177 let len = sexp.len();
178 let mut out = Vec::with_capacity(len);
179
180 for i in 0..len {
181 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
182 let value: &'static $t = TryFromSexp::try_from_sexp(elem)?;
183 out.push(value);
184 }
185
186 Ok(out)
187 }
188 }
189
190 impl TryFromSexp for Vec<Option<&'static $t>> {
191 type Error = SexpError;
192
193 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
194 let actual = sexp.type_of();
195 if actual != SEXPTYPE::VECSXP {
196 return Err(SexpTypeError {
197 expected: SEXPTYPE::VECSXP,
198 actual,
199 }
200 .into());
201 }
202
203 let len = sexp.len();
204 let mut out = Vec::with_capacity(len);
205
206 for i in 0..len {
207 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
208 if elem.type_of() == SEXPTYPE::NILSXP {
209 out.push(None);
210 } else {
211 let value: &'static $t = TryFromSexp::try_from_sexp(elem)?;
212 out.push(Some(value));
213 }
214 }
215
216 Ok(out)
217 }
218 }
219
220 impl TryFromSexp for Vec<&'static mut $t> {
221 type Error = SexpError;
222
223 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
224 let actual = sexp.type_of();
225 if actual != SEXPTYPE::VECSXP {
226 return Err(SexpTypeError {
227 expected: SEXPTYPE::VECSXP,
228 actual,
229 }
230 .into());
231 }
232
233 let len = sexp.len();
234 let mut out = Vec::with_capacity(len);
235 let mut ptrs: Vec<*mut $t> = Vec::new();
236
237 for i in 0..len {
238 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
239 let value: &'static mut $t = TryFromSexp::try_from_sexp(elem)?;
240 let ptr = std::ptr::from_mut(value);
241 if ptrs.iter().any(|&p| p == ptr) {
242 return Err(SexpError::InvalidValue(
243 "list contains duplicate elements; cannot create multiple mutable references"
244 .to_string(),
245 ));
246 }
247 ptrs.push(ptr);
248 out.push(value);
249 }
250
251 Ok(out)
252 }
253 }
254
255 impl TryFromSexp for Vec<Option<&'static mut $t>> {
256 type Error = SexpError;
257
258 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
259 let actual = sexp.type_of();
260 if actual != SEXPTYPE::VECSXP {
261 return Err(SexpTypeError {
262 expected: SEXPTYPE::VECSXP,
263 actual,
264 }
265 .into());
266 }
267
268 let len = sexp.len();
269 let mut out = Vec::with_capacity(len);
270 let mut ptrs: Vec<*mut $t> = Vec::new();
271
272 for i in 0..len {
273 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
274 if elem.type_of() == SEXPTYPE::NILSXP {
275 out.push(None);
276 continue;
277 }
278 let value: &'static mut $t = TryFromSexp::try_from_sexp(elem)?;
279 let ptr = std::ptr::from_mut(value);
280 if ptrs.iter().any(|&p| p == ptr) {
281 return Err(SexpError::InvalidValue(
282 "list contains duplicate elements; cannot create multiple mutable references"
283 .to_string(),
284 ));
285 }
286 ptrs.push(ptr);
287 out.push(Some(value));
288 }
289
290 Ok(out)
291 }
292 }
293
294 impl TryFromSexp for Vec<&'static [$t]> {
295 type Error = SexpError;
296
297 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
298 let actual = sexp.type_of();
299 if actual != SEXPTYPE::VECSXP {
300 return Err(SexpTypeError {
301 expected: SEXPTYPE::VECSXP,
302 actual,
303 }
304 .into());
305 }
306
307 let len = sexp.len();
308 let mut out = Vec::with_capacity(len);
309
310 for i in 0..len {
311 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
312 let slice: &'static [$t] =
313 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
314 out.push(slice);
315 }
316
317 Ok(out)
318 }
319 }
320
321 impl TryFromSexp for Vec<Option<&'static [$t]>> {
322 type Error = SexpError;
323
324 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
325 let actual = sexp.type_of();
326 if actual != SEXPTYPE::VECSXP {
327 return Err(SexpTypeError {
328 expected: SEXPTYPE::VECSXP,
329 actual,
330 }
331 .into());
332 }
333
334 let len = sexp.len();
335 let mut out = Vec::with_capacity(len);
336
337 for i in 0..len {
338 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
339 if elem.type_of() == SEXPTYPE::NILSXP {
340 out.push(None);
341 } else {
342 let slice: &'static [$t] =
343 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
344 out.push(Some(slice));
345 }
346 }
347
348 Ok(out)
349 }
350 }
351
352 impl TryFromSexp for Vec<&'static mut [$t]> {
353 type Error = SexpError;
354
355 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
356 let actual = sexp.type_of();
357 if actual != SEXPTYPE::VECSXP {
358 return Err(SexpTypeError {
359 expected: SEXPTYPE::VECSXP,
360 actual,
361 }
362 .into());
363 }
364
365 let len = sexp.len();
366 let mut out = Vec::with_capacity(len);
367 let mut ptrs: Vec<*mut $t> = Vec::new();
368
369 for i in 0..len {
370 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
371 let slice: &'static mut [$t] =
372 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
373 if !slice.is_empty() {
374 let ptr = slice.as_mut_ptr();
375 if ptrs.iter().any(|&p| p == ptr) {
376 return Err(SexpError::InvalidValue(
377 "list contains duplicate elements; cannot create multiple mutable references"
378 .to_string(),
379 ));
380 }
381 ptrs.push(ptr);
382 }
383 out.push(slice);
384 }
385
386 Ok(out)
387 }
388 }
389
390 impl TryFromSexp for Vec<Option<&'static mut [$t]>> {
391 type Error = SexpError;
392
393 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
394 let actual = sexp.type_of();
395 if actual != SEXPTYPE::VECSXP {
396 return Err(SexpTypeError {
397 expected: SEXPTYPE::VECSXP,
398 actual,
399 }
400 .into());
401 }
402
403 let len = sexp.len();
404 let mut out = Vec::with_capacity(len);
405 let mut ptrs: Vec<*mut $t> = Vec::new();
406
407 for i in 0..len {
408 let elem = sexp.vector_elt(i as crate::ffi::R_xlen_t);
409 if elem.type_of() == SEXPTYPE::NILSXP {
410 out.push(None);
411 continue;
412 }
413 let slice: &'static mut [$t] =
414 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
415 if !slice.is_empty() {
416 let ptr = slice.as_mut_ptr();
417 if ptrs.iter().any(|&p| p == ptr) {
418 return Err(SexpError::InvalidValue(
419 "list contains duplicate elements; cannot create multiple mutable references"
420 .to_string(),
421 ));
422 }
423 ptrs.push(ptr);
424 }
425 out.push(Some(slice));
426 }
427
428 Ok(out)
429 }
430 }
431 };
432}
433
434impl_ref_conversions_for!(i32);
435impl_ref_conversions_for!(f64);
436impl_ref_conversions_for!(u8);
437impl_ref_conversions_for!(RLogical);
438impl_ref_conversions_for!(crate::ffi::Rcomplex);
439