miniextendr_api/from_r/
references.rs1use crate::from_r::{SexpError, SexpLengthError, SexpTypeError, TryFromSexp, map_vecsxp_with};
24use crate::{RLogical, RNativeType, SEXP, SEXPTYPE, SexpExt};
25
26macro_rules! impl_ref_conversions_for {
27 ($t:ty) => {
28 impl TryFromSexp for &'static $t {
29 type Error = SexpError;
30
31 #[inline]
32 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
33 let actual = sexp.type_of();
34 if actual != <$t as RNativeType>::SEXP_TYPE {
35 return Err(SexpTypeError {
36 expected: <$t as RNativeType>::SEXP_TYPE,
37 actual,
38 }
39 .into());
40 }
41 let len = sexp.len();
42 if len != 1 {
43 return Err(SexpLengthError {
44 expected: 1,
45 actual: len,
46 }
47 .into());
48 }
49 unsafe { sexp.as_slice::<$t>() }
50 .first()
51 .ok_or_else(|| SexpLengthError { expected: 1, actual: 0 }.into())
52 }
53
54 #[inline]
55 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
56 let actual = sexp.type_of();
57 if actual != <$t as RNativeType>::SEXP_TYPE {
58 return Err(SexpTypeError {
59 expected: <$t as RNativeType>::SEXP_TYPE,
60 actual,
61 }
62 .into());
63 }
64 let len = unsafe { sexp.len_unchecked() };
65 if len != 1 {
66 return Err(SexpLengthError {
67 expected: 1,
68 actual: len,
69 }
70 .into());
71 }
72 unsafe { sexp.as_slice_unchecked::<$t>() }
73 .first()
74 .ok_or_else(|| SexpLengthError { expected: 1, actual: 0 }.into())
75 }
76 }
77
78 impl TryFromSexp for &'static mut $t {
84 type Error = SexpError;
85
86 #[inline]
87 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
88 let actual = sexp.type_of();
89 if actual != <$t as RNativeType>::SEXP_TYPE {
90 return Err(SexpTypeError {
91 expected: <$t as RNativeType>::SEXP_TYPE,
92 actual,
93 }
94 .into());
95 }
96 let len = sexp.len();
97 if len != 1 {
98 return Err(SexpLengthError {
99 expected: 1,
100 actual: len,
101 }
102 .into());
103 }
104 let ptr = unsafe { <$t as RNativeType>::dataptr_mut(sexp) };
105 Ok(unsafe { &mut *ptr })
106 }
107
108 #[inline]
109 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
110 let actual = sexp.type_of();
111 if actual != <$t as RNativeType>::SEXP_TYPE {
112 return Err(SexpTypeError {
113 expected: <$t as RNativeType>::SEXP_TYPE,
114 actual,
115 }
116 .into());
117 }
118 let len = unsafe { sexp.len_unchecked() };
119 if len != 1 {
120 return Err(SexpLengthError {
121 expected: 1,
122 actual: len,
123 }
124 .into());
125 }
126 let ptr = unsafe { <$t as RNativeType>::dataptr_mut(sexp) };
127 Ok(unsafe { &mut *ptr })
128 }
129 }
130
131 impl TryFromSexp for Option<&'static $t> {
132 type Error = SexpError;
133
134 #[inline]
135 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
136 if sexp.type_of() == SEXPTYPE::NILSXP {
137 return Ok(None);
138 }
139 let value: &'static $t = TryFromSexp::try_from_sexp(sexp)?;
140 Ok(Some(value))
141 }
142
143 #[inline]
144 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
145 if sexp.type_of() == SEXPTYPE::NILSXP {
146 return Ok(None);
147 }
148 let value: &'static $t = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
149 Ok(Some(value))
150 }
151 }
152
153 impl TryFromSexp for Option<&'static mut $t> {
154 type Error = SexpError;
155
156 #[inline]
157 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
158 if sexp.type_of() == SEXPTYPE::NILSXP {
159 return Ok(None);
160 }
161 let value: &'static mut $t = TryFromSexp::try_from_sexp(sexp)?;
162 Ok(Some(value))
163 }
164
165 #[inline]
166 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
167 if sexp.type_of() == SEXPTYPE::NILSXP {
168 return Ok(None);
169 }
170 let value: &'static mut $t =
171 unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
172 Ok(Some(value))
173 }
174 }
175
176 impl TryFromSexp for Vec<&'static $t> {
179 type Error = SexpError;
180
181 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
182 map_vecsxp_with(sexp, |_i, elem| TryFromSexp::try_from_sexp(elem))
183 }
184 }
185
186 impl TryFromSexp for Vec<Option<&'static $t>> {
187 type Error = SexpError;
188
189 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
190 map_vecsxp_with(sexp, |_i, elem| {
191 if elem.type_of() == SEXPTYPE::NILSXP {
192 Ok(None)
193 } else {
194 let value: &'static $t = TryFromSexp::try_from_sexp(elem)?;
195 Ok(Some(value))
196 }
197 })
198 }
199 }
200
201 impl TryFromSexp for Vec<&'static mut $t> {
202 type Error = SexpError;
203
204 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
205 let mut ptrs: Vec<*mut $t> = Vec::new();
206 map_vecsxp_with(sexp, |_i, elem| {
207 let value: &'static mut $t = TryFromSexp::try_from_sexp(elem)?;
208 let ptr = std::ptr::from_mut(value);
209 if ptrs.iter().any(|&p| p == ptr) {
210 return Err(SexpError::InvalidValue(
211 "list contains duplicate elements; cannot create multiple mutable references"
212 .to_string(),
213 ));
214 }
215 ptrs.push(ptr);
216 Ok(value)
217 })
218 }
219 }
220
221 impl TryFromSexp for Vec<Option<&'static mut $t>> {
222 type Error = SexpError;
223
224 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
225 let mut ptrs: Vec<*mut $t> = Vec::new();
226 map_vecsxp_with(sexp, |_i, elem| {
227 if elem.type_of() == SEXPTYPE::NILSXP {
228 return Ok(None);
229 }
230 let value: &'static mut $t = TryFromSexp::try_from_sexp(elem)?;
231 let ptr = std::ptr::from_mut(value);
232 if ptrs.iter().any(|&p| p == ptr) {
233 return Err(SexpError::InvalidValue(
234 "list contains duplicate elements; cannot create multiple mutable references"
235 .to_string(),
236 ));
237 }
238 ptrs.push(ptr);
239 Ok(Some(value))
240 })
241 }
242 }
243
244 impl TryFromSexp for Vec<&'static [$t]> {
245 type Error = SexpError;
246
247 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
248 map_vecsxp_with(sexp, |_i, elem| {
249 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)
250 })
251 }
252 }
253
254 impl TryFromSexp for Vec<Option<&'static [$t]>> {
255 type Error = SexpError;
256
257 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
258 map_vecsxp_with(sexp, |_i, elem| {
259 if elem.type_of() == SEXPTYPE::NILSXP {
260 Ok(None)
261 } else {
262 let slice: &'static [$t] =
263 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
264 Ok(Some(slice))
265 }
266 })
267 }
268 }
269
270 impl TryFromSexp for Vec<&'static mut [$t]> {
271 type Error = SexpError;
272
273 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
274 let mut ptrs: Vec<*mut $t> = Vec::new();
275 map_vecsxp_with(sexp, |_i, elem| {
276 let slice: &'static mut [$t] =
277 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
278 if !slice.is_empty() {
279 let ptr = slice.as_mut_ptr();
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 }
288 Ok(slice)
289 })
290 }
291 }
292
293 impl TryFromSexp for Vec<Option<&'static mut [$t]>> {
294 type Error = SexpError;
295
296 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
297 let mut ptrs: Vec<*mut $t> = Vec::new();
298 map_vecsxp_with(sexp, |_i, elem| {
299 if elem.type_of() == SEXPTYPE::NILSXP {
300 return Ok(None);
301 }
302 let slice: &'static mut [$t] =
303 TryFromSexp::try_from_sexp(elem).map_err(SexpError::from)?;
304 if !slice.is_empty() {
305 let ptr = slice.as_mut_ptr();
306 if ptrs.iter().any(|&p| p == ptr) {
307 return Err(SexpError::InvalidValue(
308 "list contains duplicate elements; cannot create multiple mutable references"
309 .to_string(),
310 ));
311 }
312 ptrs.push(ptr);
313 }
314 Ok(Some(slice))
315 })
316 }
317 }
318 };
319}
320
321impl_ref_conversions_for!(i32);
322impl_ref_conversions_for!(f64);
323impl_ref_conversions_for!(u8);
324impl_ref_conversions_for!(RLogical);
325impl_ref_conversions_for!(crate::Rcomplex);
326