1use crate::altrep_traits::{NA_INTEGER, NA_LOGICAL, NA_REAL};
20use crate::into_r::IntoR;
21impl IntoR for i64 {
51 type Error = std::convert::Infallible;
52 #[inline]
53 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
54 Ok(self.into_sexp())
55 }
56 #[inline]
57 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
58 Ok(unsafe { self.into_sexp_unchecked() })
59 }
60 #[inline]
61 fn into_sexp(self) -> crate::SEXP {
62 if self > i32::MIN as i64 && self <= i32::MAX as i64 {
64 (self as i32).into_sexp()
66 } else {
67 (self as f64).into_sexp()
69 }
70 }
71 #[inline]
72 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
73 if self > i32::MIN as i64 && self <= i32::MAX as i64 {
74 unsafe { (self as i32).into_sexp_unchecked() }
75 } else {
76 unsafe { (self as f64).into_sexp_unchecked() }
77 }
78 }
79}
80
81impl IntoR for u64 {
86 type Error = std::convert::Infallible;
87 #[inline]
88 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
89 Ok(self.into_sexp())
90 }
91 #[inline]
92 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
93 Ok(unsafe { self.into_sexp_unchecked() })
94 }
95 #[inline]
96 fn into_sexp(self) -> crate::SEXP {
97 if self <= i32::MAX as u64 {
98 (self as i32).into_sexp()
99 } else {
100 (self as f64).into_sexp()
101 }
102 }
103 #[inline]
104 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
105 if self <= i32::MAX as u64 {
106 unsafe { (self as i32).into_sexp_unchecked() }
107 } else {
108 unsafe { (self as f64).into_sexp_unchecked() }
109 }
110 }
111}
112
113impl IntoR for isize {
118 type Error = std::convert::Infallible;
119 #[inline]
120 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
121 Ok((self as i64).into_sexp())
122 }
123 #[inline]
124 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
125 Ok(unsafe { self.into_sexp_unchecked() })
126 }
127 #[inline]
128 fn into_sexp(self) -> crate::SEXP {
129 (self as i64).into_sexp()
130 }
131 #[inline]
132 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
133 unsafe { (self as i64).into_sexp_unchecked() }
134 }
135}
136
137impl IntoR for usize {
142 type Error = std::convert::Infallible;
143 #[inline]
144 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
145 Ok((self as u64).into_sexp())
146 }
147 #[inline]
148 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
149 Ok(unsafe { self.into_sexp_unchecked() })
150 }
151 #[inline]
152 fn into_sexp(self) -> crate::SEXP {
153 (self as u64).into_sexp()
154 }
155 #[inline]
156 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
157 unsafe { (self as u64).into_sexp_unchecked() }
158 }
159}
160
161macro_rules! impl_logical_into_r {
163 ($ty:ty, $to_i32:expr) => {
164 impl IntoR for $ty {
165 type Error = std::convert::Infallible;
166 #[inline]
167 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
168 Ok(crate::SEXP::scalar_logical_raw($to_i32(self)))
169 }
170 #[inline]
171 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
172 Ok(unsafe { self.into_sexp_unchecked() })
173 }
174 #[inline]
175 fn into_sexp(self) -> crate::SEXP {
176 crate::SEXP::scalar_logical_raw($to_i32(self))
177 }
178 #[inline]
179 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
180 unsafe { crate::SEXP::scalar_logical_raw_unchecked($to_i32(self)) }
181 }
182 }
183 };
184}
185
186impl_logical_into_r!(bool, |v: bool| i32::from(v));
187impl_logical_into_r!(crate::Rboolean, |v: crate::Rboolean| v as i32);
188impl_logical_into_r!(crate::RLogical, crate::RLogical::to_i32);
189
190impl IntoR for Option<i32> {
191 type Error = std::convert::Infallible;
192 #[inline]
193 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
194 Ok(self.into_sexp())
195 }
196 #[inline]
197 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
198 Ok(unsafe { self.into_sexp_unchecked() })
199 }
200 #[inline]
201 fn into_sexp(self) -> crate::SEXP {
202 match self {
203 Some(v) => v.into_sexp(),
204 None => crate::SEXP::scalar_integer(NA_INTEGER),
205 }
206 }
207 #[inline]
208 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
209 match self {
210 Some(v) => unsafe { v.into_sexp_unchecked() },
211 None => unsafe { crate::SEXP::scalar_integer_unchecked(NA_INTEGER) },
212 }
213 }
214}
215
216impl IntoR for Option<f64> {
217 type Error = std::convert::Infallible;
218 #[inline]
219 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
220 Ok(self.into_sexp())
221 }
222 #[inline]
223 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
224 Ok(unsafe { self.into_sexp_unchecked() })
225 }
226 #[inline]
227 fn into_sexp(self) -> crate::SEXP {
228 match self {
229 Some(v) => v.into_sexp(),
230 None => crate::SEXP::scalar_real(NA_REAL),
231 }
232 }
233 #[inline]
234 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
235 match self {
236 Some(v) => unsafe { v.into_sexp_unchecked() },
237 None => unsafe { crate::SEXP::scalar_real_unchecked(NA_REAL) },
238 }
239 }
240}
241
242impl IntoR for Option<crate::Rboolean> {
243 type Error = std::convert::Infallible;
244 #[inline]
245 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
246 Ok(self.into_sexp())
247 }
248 #[inline]
249 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
250 Ok(unsafe { self.into_sexp_unchecked() })
251 }
252 #[inline]
253 fn into_sexp(self) -> crate::SEXP {
254 match self {
255 Some(v) => crate::SEXP::scalar_logical_raw(v as i32),
257 None => crate::SEXP::scalar_logical_raw(NA_LOGICAL),
258 }
259 }
260 #[inline]
261 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
262 match self {
263 Some(v) => unsafe { crate::SEXP::scalar_logical_raw_unchecked(v as i32) },
264 None => unsafe { crate::SEXP::scalar_logical_raw_unchecked(NA_LOGICAL) },
265 }
266 }
267}
268
269impl IntoR for Option<crate::RLogical> {
270 type Error = std::convert::Infallible;
271 #[inline]
272 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
273 Ok(self.into_sexp())
274 }
275 #[inline]
276 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
277 Ok(unsafe { self.into_sexp_unchecked() })
278 }
279 #[inline]
280 fn into_sexp(self) -> crate::SEXP {
281 match self {
282 Some(v) => crate::SEXP::scalar_logical_raw(v.to_i32()),
283 None => crate::SEXP::scalar_logical_raw(NA_LOGICAL),
284 }
285 }
286 #[inline]
287 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
288 match self {
289 Some(v) => unsafe { crate::SEXP::scalar_logical_raw_unchecked(v.to_i32()) },
290 None => unsafe { crate::SEXP::scalar_logical_raw_unchecked(NA_LOGICAL) },
291 }
292 }
293}
294
295impl IntoR for Option<bool> {
296 type Error = std::convert::Infallible;
297 #[inline]
298 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
299 Ok(self.into_sexp())
300 }
301 #[inline]
302 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
303 Ok(unsafe { self.into_sexp_unchecked() })
304 }
305 #[inline]
306 fn into_sexp(self) -> crate::SEXP {
307 match self {
308 Some(v) => v.into_sexp(),
309 None => crate::SEXP::scalar_logical_raw(NA_LOGICAL),
310 }
311 }
312 #[inline]
313 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
314 match self {
315 Some(v) => unsafe { v.into_sexp_unchecked() },
316 None => unsafe { crate::SEXP::scalar_logical_raw_unchecked(NA_LOGICAL) },
317 }
318 }
319}
320
321macro_rules! impl_option_smart_i64_into_r {
325 ($t:ty, $fits_i32:expr) => {
326 impl IntoR for Option<$t> {
327 type Error = std::convert::Infallible;
328 #[inline]
329 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
330 Ok(self.into_sexp())
331 }
332 #[inline]
333 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
334 self.try_into_sexp()
335 }
336 #[inline]
337 fn into_sexp(self) -> crate::SEXP {
338 match self {
339 Some(x) if $fits_i32(x) => (x as i32).into_sexp(),
340 Some(x) => (x as f64).into_sexp(),
341 None => crate::SEXP::scalar_integer(NA_INTEGER),
342 }
343 }
344 }
345 };
346}
347
348impl_option_smart_i64_into_r!(i64, |x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64);
349impl_option_smart_i64_into_r!(u64, |x: u64| x <= i32::MAX as u64);
350impl_option_smart_i64_into_r!(isize, |x: isize| x > i32::MIN as isize
351 && x <= i32::MAX as isize);
352impl_option_smart_i64_into_r!(usize, |x: usize| x <= i32::MAX as usize);
353
354macro_rules! impl_option_coerce_into_r {
356 ($from:ty => $to:ty) => {
357 impl IntoR for Option<$from> {
358 type Error = std::convert::Infallible;
359 #[inline]
360 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
361 Ok(self.map(|x| x as $to).into_sexp())
362 }
363 #[inline]
364 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
365 self.try_into_sexp()
366 }
367 #[inline]
368 fn into_sexp(self) -> crate::SEXP {
369 self.map(|x| x as $to).into_sexp()
370 }
371 }
372 };
373}
374
375impl_option_coerce_into_r!(i8 => i32);
376impl_option_coerce_into_r!(i16 => i32);
377impl_option_coerce_into_r!(u16 => i32);
378impl_option_coerce_into_r!(u32 => i64); impl_option_coerce_into_r!(f32 => f64);
380
381impl<T: crate::externalptr::TypedExternal> IntoR for crate::externalptr::ExternalPtr<T> {
382 type Error = std::convert::Infallible;
383 #[inline]
384 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
385 Ok(self.as_sexp())
386 }
387 #[inline]
388 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
389 Ok(self.as_sexp())
390 }
391 #[inline]
392 fn into_sexp(self) -> crate::SEXP {
393 self.as_sexp()
394 }
395}
396
397impl<T: crate::externalptr::TypedExternal> IntoR for Vec<crate::externalptr::ExternalPtr<T>> {
405 type Error = std::convert::Infallible;
406 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
407 Ok(self.into_sexp())
408 }
409 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
410 self.try_into_sexp()
411 }
412 fn into_sexp(self) -> crate::SEXP {
413 vec_externalptr_to_list(self)
414 }
415}
416
417impl<T: crate::externalptr::TypedExternal> IntoR
420 for Vec<Option<crate::externalptr::ExternalPtr<T>>>
421{
422 type Error = std::convert::Infallible;
423 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
424 Ok(self.into_sexp())
425 }
426 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
427 self.try_into_sexp()
428 }
429 fn into_sexp(self) -> crate::SEXP {
430 vec_option_externalptr_to_list(self)
431 }
432}
433
434fn vec_externalptr_to_list<T: crate::externalptr::TypedExternal>(
452 items: Vec<crate::externalptr::ExternalPtr<T>>,
453) -> crate::SEXP {
454 use crate::SexpExt;
455 unsafe {
459 let n = items.len();
460 let list = crate::sys::Rf_allocVector(crate::SEXPTYPE::VECSXP, n as crate::R_xlen_t);
461 for (i, item) in items.iter().enumerate() {
462 list.set_vector_elt(i as crate::R_xlen_t, item.as_sexp());
463 }
464 list
465 }
466}
467
468fn vec_option_externalptr_to_list<T: crate::externalptr::TypedExternal>(
470 items: Vec<Option<crate::externalptr::ExternalPtr<T>>>,
471) -> crate::SEXP {
472 use crate::SexpExt;
473 unsafe {
476 let n = items.len();
477 let list = crate::sys::Rf_allocVector(crate::SEXPTYPE::VECSXP, n as crate::R_xlen_t);
478 for (i, item) in items.iter().enumerate() {
479 let elt = match item {
480 Some(ext) => ext.as_sexp(),
481 None => crate::SEXP::nil(),
482 };
483 list.set_vector_elt(i as crate::R_xlen_t, elt);
484 }
485 list
486 }
487}
488
489impl<T: crate::externalptr::IntoExternalPtr> IntoR for T {
494 type Error = std::convert::Infallible;
495 #[inline]
496 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
497 Ok(self.into_sexp())
498 }
499 #[inline]
500 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
501 Ok(unsafe { self.into_sexp_unchecked() })
502 }
503 #[inline]
504 fn into_sexp(self) -> crate::SEXP {
505 crate::externalptr::ExternalPtr::new(self).into_sexp()
506 }
507 #[inline]
508 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
509 unsafe { crate::externalptr::ExternalPtr::new_unchecked(self).into_sexp() }
510 }
511}
512
513#[inline]
516pub(crate) fn str_to_charsxp(s: &str) -> crate::SEXP {
517 if s.is_empty() {
518 crate::SEXP::blank_string()
519 } else {
520 let _len: i32 = s.len().try_into().expect("string exceeds i32::MAX bytes");
521 crate::SEXP::charsxp(s)
522 }
523}
524
525#[inline]
527pub(crate) unsafe fn str_to_charsxp_unchecked(s: &str) -> crate::SEXP {
528 unsafe {
529 if s.is_empty() {
530 crate::SEXP::blank_string()
531 } else {
532 let len: i32 = s.len().try_into().expect("string exceeds i32::MAX bytes");
533 crate::sys::Rf_mkCharLenCE_unchecked(s.as_ptr().cast(), len, crate::sexp_types::CE_UTF8)
534 }
535 }
536}
537
538impl IntoR for String {
539 type Error = crate::into_r_error::IntoRError;
540 #[inline]
541 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
542 self.as_str().try_into_sexp()
543 }
544 #[inline]
545 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
546 Ok(unsafe { self.into_sexp_unchecked() })
547 }
548 #[inline]
549 fn into_sexp(self) -> crate::SEXP {
550 self.as_str().into_sexp()
551 }
552 #[inline]
553 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
554 unsafe { self.as_str().into_sexp_unchecked() }
555 }
556}
557
558impl IntoR for Box<str> {
559 type Error = crate::into_r_error::IntoRError;
560 #[inline]
561 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
562 String::from(self).try_into_sexp()
565 }
566 #[inline]
567 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
568 Ok(unsafe { self.into_sexp_unchecked() })
569 }
570 #[inline]
571 fn into_sexp(self) -> crate::SEXP {
572 String::from(self).into_sexp()
573 }
574 #[inline]
575 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
576 unsafe { String::from(self).into_sexp_unchecked() }
577 }
578}
579
580impl IntoR for char {
581 type Error = std::convert::Infallible;
582 #[inline]
583 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
584 Ok(self.into_sexp())
585 }
586 #[inline]
587 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
588 Ok(unsafe { self.into_sexp_unchecked() })
589 }
590 #[inline]
591 fn into_sexp(self) -> crate::SEXP {
592 let mut buf = [0u8; 4];
594 let s = self.encode_utf8(&mut buf);
595 crate::SEXP::scalar_string(str_to_charsxp(s))
596 }
597 #[inline]
598 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
599 let mut buf = [0u8; 4];
600 let s = self.encode_utf8(&mut buf);
601 unsafe { s.into_sexp_unchecked() }
602 }
603}
604
605impl IntoR for &str {
606 type Error = crate::into_r_error::IntoRError;
607 #[inline]
608 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
609 let _len = i32::try_from(self.len())
610 .map_err(|_| crate::into_r_error::IntoRError::StringTooLong { len: self.len() })?;
611 Ok(crate::SEXP::scalar_string(str_to_charsxp(self)))
612 }
613 #[inline]
614 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
615 Ok(unsafe { self.into_sexp_unchecked() })
616 }
617 #[inline]
618 fn into_sexp(self) -> crate::SEXP {
619 crate::SEXP::scalar_string(str_to_charsxp(self))
620 }
621 #[inline]
622 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
623 unsafe {
624 let charsxp = str_to_charsxp_unchecked(self);
625 crate::SEXP::scalar_string_unchecked(charsxp)
626 }
627 }
628}
629
630impl IntoR for Option<&str> {
640 type Error = crate::into_r_error::IntoRError;
641 #[inline]
642 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
643 match self {
644 Some(s) => {
645 let _len = i32::try_from(s.len())
646 .map_err(|_| crate::into_r_error::IntoRError::StringTooLong { len: s.len() })?;
647 Ok(crate::SEXP::scalar_string(str_to_charsxp(s)))
648 }
649 None => Ok(crate::SEXP::scalar_string(crate::SEXP::na_string())),
650 }
651 }
652 #[inline]
653 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
654 Ok(unsafe { self.into_sexp_unchecked() })
655 }
656 #[inline]
657 fn into_sexp(self) -> crate::SEXP {
658 let charsxp = match self {
659 Some(s) => str_to_charsxp(s),
660 None => crate::SEXP::na_string(),
661 };
662 crate::SEXP::scalar_string(charsxp)
663 }
664 #[inline]
665 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
666 unsafe {
667 let charsxp = match self {
668 Some(s) => str_to_charsxp_unchecked(s),
669 None => crate::SEXP::na_string(),
670 };
671 crate::SEXP::scalar_string_unchecked(charsxp)
672 }
673 }
674}
675
676impl IntoR for Option<String> {
677 type Error = crate::into_r_error::IntoRError;
678 #[inline]
679 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
680 self.as_deref().try_into_sexp()
681 }
682 #[inline]
683 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
684 Ok(unsafe { self.into_sexp_unchecked() })
685 }
686 #[inline]
687 fn into_sexp(self) -> crate::SEXP {
688 self.as_deref().into_sexp()
689 }
690 #[inline]
691 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
692 unsafe { self.as_deref().into_sexp_unchecked() }
693 }
694}
695
696impl<T> IntoR for Option<&T>
708where
709 T: Copy + IntoR,
710{
711 type Error = crate::into_r_error::IntoRError;
712 #[inline]
713 fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
714 match self {
715 Some(&v) => v
716 .try_into_sexp()
717 .map_err(|e| crate::into_r_error::IntoRError::Inner(e.to_string())),
718 None => Ok(crate::SEXP::nil()),
719 }
720 }
721 #[inline]
722 unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
723 Ok(unsafe { self.into_sexp_unchecked() })
724 }
725 #[inline]
726 fn into_sexp(self) -> crate::SEXP {
727 match self {
728 Some(&v) => v.into_sexp(),
729 None => crate::SEXP::nil(),
730 }
731 }
732 #[inline]
733 unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
734 match self {
735 Some(&v) => unsafe { v.into_sexp_unchecked() },
736 None => crate::SEXP::nil(),
737 }
738 }
739}
740
741