1use crate::coerce::TryCoerce;
10use crate::ffi::{RLogical, SEXP, SEXPTYPE, SexpExt};
11use crate::from_r::{SexpError, TryFromSexp, is_na_real};
12
13#[inline]
14pub(crate) fn coerce_value<R, T>(value: R) -> Result<T, SexpError>
15where
16 R: TryCoerce<T>,
17 <R as TryCoerce<T>>::Error: std::fmt::Debug,
18{
19 value
20 .try_coerce()
21 .map_err(|e| SexpError::InvalidValue(format!("{e:?}")))
22}
23
24#[inline]
25fn try_from_sexp_numeric_scalar<T>(sexp: SEXP) -> Result<T, SexpError>
26where
27 i32: TryCoerce<T>,
28 f64: TryCoerce<T>,
29 u8: TryCoerce<T>,
30 <i32 as TryCoerce<T>>::Error: std::fmt::Debug,
31 <f64 as TryCoerce<T>>::Error: std::fmt::Debug,
32 <u8 as TryCoerce<T>>::Error: std::fmt::Debug,
33{
34 let actual = sexp.type_of();
35 match actual {
36 SEXPTYPE::INTSXP => {
37 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
38 coerce_value(value)
39 }
40 SEXPTYPE::REALSXP => {
41 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
42 coerce_value(value)
43 }
44 SEXPTYPE::RAWSXP => {
45 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
46 coerce_value(value)
47 }
48 SEXPTYPE::LGLSXP => {
49 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
50 coerce_value(value.to_i32())
51 }
52 _ => Err(SexpError::InvalidValue(format!(
53 "expected integer, numeric, logical, or raw; got {:?}",
54 actual
55 ))),
56 }
57}
58
59#[inline]
60unsafe fn try_from_sexp_numeric_scalar_unchecked<T>(sexp: SEXP) -> Result<T, SexpError>
61where
62 i32: TryCoerce<T>,
63 f64: TryCoerce<T>,
64 u8: TryCoerce<T>,
65 <i32 as TryCoerce<T>>::Error: std::fmt::Debug,
66 <f64 as TryCoerce<T>>::Error: std::fmt::Debug,
67 <u8 as TryCoerce<T>>::Error: std::fmt::Debug,
68{
69 let actual = sexp.type_of();
70 match actual {
71 SEXPTYPE::INTSXP => {
72 let value: i32 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
73 coerce_value(value)
74 }
75 SEXPTYPE::REALSXP => {
76 let value: f64 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
77 coerce_value(value)
78 }
79 SEXPTYPE::RAWSXP => {
80 let value: u8 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
81 coerce_value(value)
82 }
83 SEXPTYPE::LGLSXP => {
84 let value: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
85 coerce_value(value.to_i32())
86 }
87 _ => Err(SexpError::InvalidValue(format!(
88 "expected integer, numeric, logical, or raw; got {:?}",
89 actual
90 ))),
91 }
92}
93
94#[inline]
95fn try_from_sexp_numeric_option<T>(sexp: SEXP) -> Result<Option<T>, SexpError>
96where
97 i32: TryCoerce<T>,
98 f64: TryCoerce<T>,
99 u8: TryCoerce<T>,
100 <i32 as TryCoerce<T>>::Error: std::fmt::Debug,
101 <f64 as TryCoerce<T>>::Error: std::fmt::Debug,
102 <u8 as TryCoerce<T>>::Error: std::fmt::Debug,
103{
104 if sexp.type_of() == SEXPTYPE::NILSXP {
105 return Ok(None);
106 }
107
108 let actual = sexp.type_of();
109 match actual {
110 SEXPTYPE::INTSXP => {
111 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
112 if value == crate::altrep_traits::NA_INTEGER {
113 Ok(None)
114 } else {
115 coerce_value(value).map(Some)
116 }
117 }
118 SEXPTYPE::REALSXP => {
119 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
120 if is_na_real(value) {
121 Ok(None)
122 } else {
123 coerce_value(value).map(Some)
124 }
125 }
126 SEXPTYPE::RAWSXP => {
127 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
128 coerce_value(value).map(Some)
129 }
130 SEXPTYPE::LGLSXP => {
131 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
132 if value.is_na() {
133 Ok(None)
134 } else {
135 coerce_value(value.to_i32()).map(Some)
136 }
137 }
138 _ => Err(SexpError::InvalidValue(format!(
139 "expected integer, numeric, logical, or raw; got {:?}",
140 actual
141 ))),
142 }
143}
144
145#[inline]
146unsafe fn try_from_sexp_numeric_option_unchecked<T>(sexp: SEXP) -> Result<Option<T>, SexpError>
147where
148 i32: TryCoerce<T>,
149 f64: TryCoerce<T>,
150 u8: TryCoerce<T>,
151 <i32 as TryCoerce<T>>::Error: std::fmt::Debug,
152 <f64 as TryCoerce<T>>::Error: std::fmt::Debug,
153 <u8 as TryCoerce<T>>::Error: std::fmt::Debug,
154{
155 if sexp.type_of() == SEXPTYPE::NILSXP {
156 return Ok(None);
157 }
158
159 let actual = sexp.type_of();
160 match actual {
161 SEXPTYPE::INTSXP => {
162 let value: i32 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
163 if value == crate::altrep_traits::NA_INTEGER {
164 Ok(None)
165 } else {
166 coerce_value(value).map(Some)
167 }
168 }
169 SEXPTYPE::REALSXP => {
170 let value: f64 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
171 if is_na_real(value) {
172 Ok(None)
173 } else {
174 coerce_value(value).map(Some)
175 }
176 }
177 SEXPTYPE::RAWSXP => {
178 let value: u8 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
179 coerce_value(value).map(Some)
180 }
181 SEXPTYPE::LGLSXP => {
182 let value: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
183 if value.is_na() {
184 Ok(None)
185 } else {
186 coerce_value(value.to_i32()).map(Some)
187 }
188 }
189 _ => Err(SexpError::InvalidValue(format!(
190 "expected integer, numeric, logical, or raw; got {:?}",
191 actual
192 ))),
193 }
194}
195
196impl TryFromSexp for i8 {
197 type Error = SexpError;
198
199 #[inline]
200 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
201 try_from_sexp_numeric_scalar(sexp)
202 }
203
204 #[inline]
205 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
206 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
207 }
208}
209
210impl TryFromSexp for i16 {
211 type Error = SexpError;
212
213 #[inline]
214 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
215 try_from_sexp_numeric_scalar(sexp)
216 }
217
218 #[inline]
219 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
220 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
221 }
222}
223
224impl TryFromSexp for u16 {
225 type Error = SexpError;
226
227 #[inline]
228 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
229 try_from_sexp_numeric_scalar(sexp)
230 }
231
232 #[inline]
233 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
234 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
235 }
236}
237
238impl TryFromSexp for u32 {
239 type Error = SexpError;
240
241 #[inline]
242 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
243 try_from_sexp_numeric_scalar(sexp)
244 }
245
246 #[inline]
247 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
248 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
249 }
250}
251
252impl TryFromSexp for f32 {
253 type Error = SexpError;
254
255 #[inline]
256 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
257 let actual = sexp.type_of();
258 match actual {
259 SEXPTYPE::INTSXP => {
260 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
261 Ok(value as f32)
262 }
263 SEXPTYPE::REALSXP => {
264 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
265 Ok(value as f32)
266 }
267 SEXPTYPE::RAWSXP => {
268 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
269 Ok(value as f32)
270 }
271 SEXPTYPE::LGLSXP => {
272 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
273 Ok(value.to_i32() as f32)
274 }
275 _ => Err(SexpError::InvalidValue(format!(
276 "expected integer, numeric, logical, or raw; got {:?}",
277 actual
278 ))),
279 }
280 }
281
282 #[inline]
283 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
284 let actual = sexp.type_of();
285 match actual {
286 SEXPTYPE::INTSXP => {
287 let value: i32 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
288 Ok(value as f32)
289 }
290 SEXPTYPE::REALSXP => {
291 let value: f64 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
292 Ok(value as f32)
293 }
294 SEXPTYPE::RAWSXP => {
295 let value: u8 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
296 Ok(value as f32)
297 }
298 SEXPTYPE::LGLSXP => {
299 let value: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
300 Ok(value.to_i32() as f32)
301 }
302 _ => Err(SexpError::InvalidValue(format!(
303 "expected integer, numeric, logical, or raw; got {:?}",
304 actual
305 ))),
306 }
307 }
308}
309
310impl TryFromSexp for Option<i8> {
311 type Error = SexpError;
312
313 #[inline]
314 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
315 try_from_sexp_numeric_option(sexp)
316 }
317
318 #[inline]
319 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
320 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
321 }
322}
323
324impl TryFromSexp for Option<i16> {
325 type Error = SexpError;
326
327 #[inline]
328 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
329 try_from_sexp_numeric_option(sexp)
330 }
331
332 #[inline]
333 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
334 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
335 }
336}
337
338impl TryFromSexp for Option<u16> {
339 type Error = SexpError;
340
341 #[inline]
342 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
343 try_from_sexp_numeric_option(sexp)
344 }
345
346 #[inline]
347 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
348 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
349 }
350}
351
352impl TryFromSexp for Option<u32> {
353 type Error = SexpError;
354
355 #[inline]
356 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
357 try_from_sexp_numeric_option(sexp)
358 }
359
360 #[inline]
361 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
362 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
363 }
364}
365
366impl TryFromSexp for Option<f32> {
367 type Error = SexpError;
368
369 #[inline]
370 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
371 if sexp.type_of() == SEXPTYPE::NILSXP {
372 return Ok(None);
373 }
374 let actual = sexp.type_of();
375 match actual {
376 SEXPTYPE::INTSXP => {
377 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
378 if value == crate::altrep_traits::NA_INTEGER {
379 Ok(None)
380 } else {
381 Ok(Some(value as f32))
382 }
383 }
384 SEXPTYPE::REALSXP => {
385 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
386 if is_na_real(value) {
387 Ok(None)
388 } else {
389 Ok(Some(value as f32))
390 }
391 }
392 SEXPTYPE::RAWSXP => {
393 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
394 Ok(Some(value as f32))
395 }
396 SEXPTYPE::LGLSXP => {
397 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
398 if value.is_na() {
399 Ok(None)
400 } else {
401 Ok(Some(value.to_i32() as f32))
402 }
403 }
404 _ => Err(SexpError::InvalidValue(format!(
405 "expected integer, numeric, logical, or raw; got {:?}",
406 actual
407 ))),
408 }
409 }
410
411 #[inline]
412 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
413 if sexp.type_of() == SEXPTYPE::NILSXP {
414 return Ok(None);
415 }
416 let actual = sexp.type_of();
417 match actual {
418 SEXPTYPE::INTSXP => {
419 let value: i32 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
420 if value == crate::altrep_traits::NA_INTEGER {
421 Ok(None)
422 } else {
423 Ok(Some(value as f32))
424 }
425 }
426 SEXPTYPE::REALSXP => {
427 let value: f64 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
428 if is_na_real(value) {
429 Ok(None)
430 } else {
431 Ok(Some(value as f32))
432 }
433 }
434 SEXPTYPE::RAWSXP => {
435 let value: u8 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
436 Ok(Some(value as f32))
437 }
438 SEXPTYPE::LGLSXP => {
439 let value: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
440 if value.is_na() {
441 Ok(None)
442 } else {
443 Ok(Some(value.to_i32() as f32))
444 }
445 }
446 _ => Err(SexpError::InvalidValue(format!(
447 "expected integer, numeric, logical, or raw; got {:?}",
448 actual
449 ))),
450 }
451 }
452}
453impl TryFromSexp for i64 {
492 type Error = SexpError;
493
494 #[inline]
495 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
496 try_from_sexp_numeric_scalar(sexp)
497 }
498
499 #[inline]
500 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
501 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
502 }
503}
504
505impl TryFromSexp for u64 {
510 type Error = SexpError;
511
512 #[inline]
513 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
514 try_from_sexp_numeric_scalar(sexp)
515 }
516
517 #[inline]
518 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
519 unsafe { try_from_sexp_numeric_scalar_unchecked(sexp) }
520 }
521}
522
523impl TryFromSexp for Option<i64> {
525 type Error = SexpError;
526
527 #[inline]
528 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
529 try_from_sexp_numeric_option(sexp)
530 }
531
532 #[inline]
533 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
534 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
535 }
536}
537
538impl TryFromSexp for Option<u64> {
539 type Error = SexpError;
540
541 #[inline]
542 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
543 try_from_sexp_numeric_option(sexp)
544 }
545
546 #[inline]
547 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
548 unsafe { try_from_sexp_numeric_option_unchecked(sexp) }
549 }
550}
551
552impl TryFromSexp for usize {
553 type Error = SexpError;
554
555 #[inline]
556 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
557 let actual = sexp.type_of();
559 match actual {
560 SEXPTYPE::INTSXP => {
561 use crate::coerce::TryCoerce;
562 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
563 value
564 .try_coerce()
565 .map_err(|e| SexpError::InvalidValue(format!("{e}")))
566 }
567 SEXPTYPE::REALSXP => {
568 use crate::coerce::TryCoerce;
569 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
570 let u: u64 = value
571 .try_coerce()
572 .map_err(|e| SexpError::InvalidValue(format!("{e}")))?;
573 u.try_into()
574 .map_err(|_| SexpError::InvalidValue("value out of usize range".into()))
575 }
576 SEXPTYPE::RAWSXP => {
577 use crate::coerce::Coerce;
578 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
579 Ok(value.coerce())
580 }
581 SEXPTYPE::LGLSXP => {
582 use crate::coerce::TryCoerce;
583 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
584 value
585 .to_i32()
586 .try_coerce()
587 .map_err(|e| SexpError::InvalidValue(format!("{e}")))
588 }
589 _ => Err(SexpError::InvalidValue(format!(
590 "expected integer, numeric, logical, or raw; got {:?}",
591 actual
592 ))),
593 }
594 }
595}
596
597impl TryFromSexp for Option<usize> {
598 type Error = SexpError;
599
600 #[inline]
601 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
602 if sexp.type_of() == SEXPTYPE::NILSXP {
603 return Ok(None);
604 }
605 let actual = sexp.type_of();
606 match actual {
607 SEXPTYPE::INTSXP => {
608 use crate::coerce::TryCoerce;
609 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
610 if value == crate::altrep_traits::NA_INTEGER {
611 Ok(None)
612 } else {
613 value
614 .try_coerce()
615 .map(Some)
616 .map_err(|e| SexpError::InvalidValue(format!("{e}")))
617 }
618 }
619 SEXPTYPE::REALSXP => {
620 use crate::coerce::TryCoerce;
621 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
622 if is_na_real(value) {
623 return Ok(None);
624 }
625 let u: u64 = value
626 .try_coerce()
627 .map_err(|e| SexpError::InvalidValue(format!("{e}")))?;
628 u.try_into()
629 .map(Some)
630 .map_err(|_| SexpError::InvalidValue("value out of usize range".into()))
631 }
632 SEXPTYPE::RAWSXP => {
633 use crate::coerce::Coerce;
634 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
635 Ok(Some(value.coerce()))
636 }
637 SEXPTYPE::LGLSXP => {
638 use crate::coerce::TryCoerce;
639 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
640 if value.is_na() {
641 Ok(None)
642 } else {
643 value
644 .to_i32()
645 .try_coerce()
646 .map(Some)
647 .map_err(|e| SexpError::InvalidValue(format!("{e}")))
648 }
649 }
650 _ => Err(SexpError::InvalidValue(format!(
651 "expected integer, numeric, logical, or raw; got {:?}",
652 actual
653 ))),
654 }
655 }
656
657 #[inline]
658 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
659 Self::try_from_sexp(sexp)
660 }
661}
662
663impl TryFromSexp for isize {
664 type Error = SexpError;
665
666 #[inline]
667 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
668 let actual = sexp.type_of();
670 match actual {
671 SEXPTYPE::INTSXP => {
672 use crate::coerce::Coerce;
673 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
674 Ok(value.coerce())
675 }
676 SEXPTYPE::REALSXP => {
677 use crate::coerce::TryCoerce;
678 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
679 let i: i64 = value
680 .try_coerce()
681 .map_err(|e| SexpError::InvalidValue(format!("{e}")))?;
682 i.try_into()
683 .map_err(|_| SexpError::InvalidValue("value out of isize range".into()))
684 }
685 SEXPTYPE::RAWSXP => {
686 use crate::coerce::Coerce;
687 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
688 Ok(value.coerce())
689 }
690 SEXPTYPE::LGLSXP => {
691 use crate::coerce::Coerce;
692 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
693 Ok(value.to_i32().coerce())
694 }
695 _ => Err(SexpError::InvalidValue(format!(
696 "expected integer, numeric, logical, or raw; got {:?}",
697 actual
698 ))),
699 }
700 }
701}
702
703impl TryFromSexp for Option<isize> {
704 type Error = SexpError;
705
706 #[inline]
707 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
708 if sexp.type_of() == SEXPTYPE::NILSXP {
709 return Ok(None);
710 }
711 let actual = sexp.type_of();
712 match actual {
713 SEXPTYPE::INTSXP => {
714 use crate::coerce::Coerce;
715 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
716 if value == crate::altrep_traits::NA_INTEGER {
717 Ok(None)
718 } else {
719 Ok(Some(value.coerce()))
720 }
721 }
722 SEXPTYPE::REALSXP => {
723 use crate::coerce::TryCoerce;
724 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
725 if is_na_real(value) {
726 return Ok(None);
727 }
728 let i: i64 = value
729 .try_coerce()
730 .map_err(|e| SexpError::InvalidValue(format!("{e}")))?;
731 i.try_into()
732 .map(Some)
733 .map_err(|_| SexpError::InvalidValue("value out of isize range".into()))
734 }
735 SEXPTYPE::RAWSXP => {
736 use crate::coerce::Coerce;
737 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
738 Ok(Some(value.coerce()))
739 }
740 SEXPTYPE::LGLSXP => {
741 use crate::coerce::Coerce;
742 let value: RLogical = TryFromSexp::try_from_sexp(sexp)?;
743 if value.is_na() {
744 Ok(None)
745 } else {
746 Ok(Some(value.to_i32().coerce()))
747 }
748 }
749 _ => Err(SexpError::InvalidValue(format!(
750 "expected integer, numeric, logical, or raw; got {:?}",
751 actual
752 ))),
753 }
754 }
755
756 #[inline]
757 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
758 Self::try_from_sexp(sexp)
759 }
760}
761