extendr_api/robj/
try_from_robj.rs1use super::*;
10use crate as extendr_api;
11use crate::conversions::try_into_int::FloatToInt;
12
13macro_rules! impl_try_from_scalar_integer {
14 ($t:ty) => {
15 impl TryFrom<&Robj> for $t {
16 type Error = Error;
17
18 fn try_from(robj: &Robj) -> Result<Self> {
20 match robj.len() {
22 0 => return Err(Error::ExpectedNonZeroLength(robj.clone())),
23 1 => {}
24 _ => return Err(Error::ExpectedScalar(robj.clone())),
25 };
26
27 if robj.is_na() {
29 return Err(Error::MustNotBeNA(robj.clone()));
30 }
31
32 if let Some(v) = robj.as_integer() {
37 return Self::try_from(v).map_err(|_| Error::OutOfLimits(robj.clone()));
38 }
39
40 if let Some(v) = robj.as_real() {
44 return v
45 .try_into_int()
46 .map_err(|conv_err| Error::ExpectedWholeNumber(robj.clone(), conv_err));
47 }
48
49 Err(Error::ExpectedNumeric(robj.clone()))
50 }
51 }
52 };
53}
54
55macro_rules! impl_try_from_scalar_real {
56 ($t:ty) => {
57 impl TryFrom<&Robj> for $t {
58 type Error = Error;
59
60 fn try_from(robj: &Robj) -> Result<Self> {
62 match robj.len() {
64 0 => return Err(Error::ExpectedNonZeroLength(robj.clone())),
65 1 => {}
66 _ => return Err(Error::ExpectedScalar(robj.clone())),
67 };
68
69 if robj.is_na() {
71 return Err(Error::MustNotBeNA(robj.clone()));
72 }
73
74 if let Some(v) = robj.as_real() {
78 return Ok(v as Self);
80 }
81 if let Some(v) = robj.as_integer() {
82 return Ok(v as Self);
84 }
85
86 Err(Error::ExpectedNumeric(robj.clone()))
87 }
88 }
89 };
90}
91
92impl_try_from_scalar_integer!(u8);
93impl_try_from_scalar_integer!(u16);
94impl_try_from_scalar_integer!(u32);
95impl_try_from_scalar_integer!(u64);
96impl_try_from_scalar_integer!(usize);
97impl_try_from_scalar_integer!(i8);
98impl_try_from_scalar_integer!(i16);
99impl_try_from_scalar_integer!(i32);
100impl_try_from_scalar_integer!(i64);
101impl_try_from_scalar_integer!(isize);
102impl_try_from_scalar_real!(f32);
103impl_try_from_scalar_real!(f64);
104
105impl TryFrom<&Robj> for bool {
106 type Error = Error;
107
108 fn try_from(robj: &Robj) -> Result<Self> {
111 if robj.is_na() {
112 Err(Error::MustNotBeNA(robj.clone()))
113 } else {
114 Ok(<Rbool>::try_from(robj)?.is_true())
115 }
116 }
117}
118
119impl TryFrom<&Robj> for &str {
120 type Error = Error;
121
122 fn try_from(robj: &Robj) -> Result<Self> {
125 if robj.is_na() {
126 return Err(Error::MustNotBeNA(robj.clone()));
127 }
128 match robj.len() {
129 0 => Err(Error::ExpectedNonZeroLength(robj.clone())),
130 1 => {
131 if let Some(s) = robj.as_str() {
132 Ok(s)
133 } else {
134 Err(Error::ExpectedString(robj.clone()))
135 }
136 }
137 _ => Err(Error::ExpectedScalar(robj.clone())),
138 }
139 }
140}
141
142impl TryFrom<&Robj> for String {
143 type Error = Error;
144
145 fn try_from(robj: &Robj) -> Result<Self> {
149 <&str>::try_from(robj).map(|s| s.to_string())
150 }
151}
152
153impl TryFrom<&Robj> for Vec<i32> {
154 type Error = Error;
155
156 fn try_from(robj: &Robj) -> Result<Self> {
160 if let Some(v) = robj.as_typed_slice() {
161 Ok(Vec::from(v))
163 } else {
164 Err(Error::ExpectedInteger(robj.clone()))
165 }
166 }
167}
168
169impl TryFrom<&Robj> for Vec<f64> {
170 type Error = Error;
171
172 fn try_from(robj: &Robj) -> Result<Self> {
176 if let Some(v) = robj.as_typed_slice() {
177 Ok(Vec::from(v))
179 } else {
180 Err(Error::ExpectedReal(robj.clone()))
181 }
182 }
183}
184
185impl TryFrom<&Robj> for Vec<u8> {
186 type Error = Error;
187
188 fn try_from(robj: &Robj) -> Result<Self> {
191 if let Some(v) = robj.as_typed_slice() {
192 Ok(Vec::from(v))
193 } else {
194 Err(Error::ExpectedRaw(robj.clone()))
195 }
196 }
197}
198
199impl TryFrom<&Robj> for Vec<Rint> {
200 type Error = Error;
201
202 fn try_from(robj: &Robj) -> Result<Self> {
206 if let Some(v) = robj.as_typed_slice() {
207 Ok(Vec::from(v))
208 } else {
209 Err(Error::ExpectedInteger(robj.clone()))
210 }
211 }
212}
213
214impl TryFrom<&Robj> for Vec<Rfloat> {
215 type Error = Error;
216
217 fn try_from(robj: &Robj) -> Result<Self> {
221 if let Some(v) = robj.as_typed_slice() {
222 Ok(Vec::from(v))
223 } else {
224 Err(Error::ExpectedReal(robj.clone()))
225 }
226 }
227}
228
229impl TryFrom<&Robj> for Vec<Rbool> {
230 type Error = Error;
231
232 fn try_from(robj: &Robj) -> Result<Self> {
236 if let Some(v) = robj.as_typed_slice() {
237 Ok(Vec::from(v))
238 } else {
239 Err(Error::ExpectedInteger(robj.clone()))
240 }
241 }
242}
243
244impl TryFrom<&Robj> for Vec<Rcplx> {
245 type Error = Error;
246
247 fn try_from(robj: &Robj) -> Result<Self> {
249 if let Some(v) = robj.as_typed_slice() {
250 Ok(Vec::from(v))
251 } else {
252 Err(Error::ExpectedComplex(robj.clone()))
253 }
254 }
255}
256
257impl TryFrom<&Robj> for Vec<String> {
258 type Error = Error;
259
260 fn try_from(robj: &Robj) -> Result<Self> {
263 if let Some(iter) = robj.as_str_iter() {
264 if iter.clone().any(|s| s.is_na()) {
266 Err(Error::MustNotBeNA(robj.clone()))
267 } else {
268 Ok(iter.map(|s| s.to_string()).collect::<Vec<String>>())
269 }
270 } else {
271 Err(Error::ExpectedString(robj.clone()))
272 }
273 }
274}
275
276impl TryFrom<&Robj> for &[i32] {
277 type Error = Error;
278
279 fn try_from(robj: &Robj) -> Result<Self> {
282 robj.as_typed_slice()
283 .ok_or_else(|| Error::ExpectedInteger(robj.clone()))
284 }
285}
286
287impl TryFrom<&Robj> for &[Rint] {
288 type Error = Error;
289
290 fn try_from(robj: &Robj) -> Result<Self> {
293 robj.as_typed_slice()
294 .ok_or_else(|| Error::ExpectedInteger(robj.clone()))
295 }
296}
297
298impl TryFrom<&Robj> for &[Rfloat] {
299 type Error = Error;
300
301 fn try_from(robj: &Robj) -> Result<Self> {
304 robj.as_typed_slice()
305 .ok_or_else(|| Error::ExpectedReal(robj.clone()))
306 }
307}
308
309impl TryFrom<&Robj> for &[Rbool] {
310 type Error = Error;
311
312 fn try_from(robj: &Robj) -> Result<Self> {
315 robj.as_typed_slice()
316 .ok_or_else(|| Error::ExpectedLogical(robj.clone()))
317 }
318}
319
320impl TryFrom<&Robj> for &[Rcplx] {
321 type Error = Error;
322
323 fn try_from(robj: &Robj) -> Result<Self> {
326 robj.as_typed_slice()
327 .ok_or_else(|| Error::ExpectedComplex(robj.clone()))
328 }
329}
330
331impl TryFrom<&Robj> for &[u8] {
332 type Error = Error;
333
334 fn try_from(robj: &Robj) -> Result<Self> {
336 robj.as_typed_slice()
337 .ok_or_else(|| Error::ExpectedRaw(robj.clone()))
338 }
339}
340
341impl TryFrom<&Robj> for &[f64] {
342 type Error = Error;
343
344 fn try_from(robj: &Robj) -> Result<Self> {
347 robj.as_typed_slice()
348 .ok_or_else(|| Error::ExpectedReal(robj.clone()))
349 }
350}
351
352impl TryFrom<&mut Robj> for &mut [i32] {
353 type Error = Error;
354
355 fn try_from(robj: &mut Robj) -> Result<Self> {
358 robj.as_typed_slice_mut()
359 .ok_or_else(|| Error::ExpectedInteger(robj.clone()))
360 }
361}
362
363impl TryFrom<&mut Robj> for &mut [Rint] {
364 type Error = Error;
365
366 fn try_from(robj: &mut Robj) -> Result<Self> {
369 robj.as_typed_slice_mut()
370 .ok_or_else(|| Error::ExpectedInteger(robj.clone()))
371 }
372}
373
374impl TryFrom<&mut Robj> for &mut [Rfloat] {
375 type Error = Error;
376
377 fn try_from(robj: &mut Robj) -> Result<Self> {
380 robj.as_typed_slice_mut()
381 .ok_or_else(|| Error::ExpectedReal(robj.clone()))
382 }
383}
384
385impl TryFrom<&mut Robj> for &mut [Rbool] {
386 type Error = Error;
387
388 fn try_from(robj: &mut Robj) -> Result<Self> {
391 robj.as_typed_slice_mut()
392 .ok_or_else(|| Error::ExpectedLogical(robj.clone()))
393 }
394}
395
396impl TryFrom<&mut Robj> for &mut [Rcplx] {
397 type Error = Error;
398
399 fn try_from(robj: &mut Robj) -> Result<Self> {
402 robj.as_typed_slice_mut()
403 .ok_or_else(|| Error::ExpectedComplex(robj.clone()))
404 }
405}
406
407impl TryFrom<&mut Robj> for &mut [u8] {
408 type Error = Error;
409
410 fn try_from(robj: &mut Robj) -> Result<Self> {
412 robj.as_typed_slice_mut()
413 .ok_or_else(|| Error::ExpectedRaw(robj.clone()))
414 }
415}
416
417impl TryFrom<&mut Robj> for &mut [f64] {
418 type Error = Error;
419
420 fn try_from(robj: &mut Robj) -> Result<Self> {
423 robj.as_typed_slice_mut()
424 .ok_or_else(|| Error::ExpectedReal(robj.clone()))
425 }
426}
427
428impl TryFrom<&Robj> for Rcplx {
429 type Error = Error;
430
431 fn try_from(robj: &Robj) -> Result<Self> {
432 match robj.len() {
434 0 => return Err(Error::ExpectedNonZeroLength(robj.clone())),
435 1 => {}
436 _ => return Err(Error::ExpectedScalar(robj.clone())),
437 };
438
439 if robj.is_na() {
441 return Ok(Rcplx::na());
442 }
443
444 if let Some(v) = robj.as_real() {
446 return Ok(Rcplx::from(v));
447 }
448
449 if let Some(v) = robj.as_integer() {
452 return Ok(Rcplx::from(v as f64));
453 }
454
455 if let Some(s) = robj.as_typed_slice() {
457 return Ok(s[0]);
458 }
459
460 Err(Error::ExpectedComplex(robj.clone()))
461 }
462}
463
464macro_rules! impl_try_from_robj {
467 (&mut [$type:ty]) => {
468 impl TryFrom<Robj> for &mut [$type] {
469 type Error = Error;
470
471 fn try_from(mut robj: Robj) -> Result<Self> {
472 Self::try_from(&mut robj)
473 }
474 }
475
476 impl TryFrom<&mut Robj> for Option<&mut [$type]> {
477 type Error = Error;
478
479 fn try_from(robj: &mut Robj) -> Result<Self> {
480 if robj.is_null() || robj.is_na() {
481 Ok(None)
482 } else {
483 Ok(Some(<&mut [$type]>::try_from(robj)?))
484 }
485 }
486 }
487
488 impl TryFrom<Robj> for Option<&mut [$type]> {
489 type Error = Error;
490
491 fn try_from(mut robj: Robj) -> Result<Self> {
492 Self::try_from(&mut robj)
493 }
494 }
495 };
496 ($(@generics<$generics:tt>)? $type:ty $(where $($where_clause:tt)*)?) => {
497 impl$(<$generics>)? TryFrom<Robj> for $type $(where $($where_clause)*)? {
498 type Error = Error;
499
500 fn try_from(robj: Robj) -> Result<Self> {
501 Self::try_from(&robj)
502 }
503 }
504
505 impl$(<$generics>)? TryFrom<&Robj> for Option<$type> $(where $($where_clause)*)? {
506 type Error = Error;
507
508 fn try_from(robj: &Robj) -> Result<Self> {
509 if robj.is_null() || robj.is_na() {
510 Ok(None)
511 } else {
512 Ok(Some(<$type>::try_from(robj)?))
513 }
514 }
515 }
516
517 impl$(<$generics>)? TryFrom<Robj> for Option<$type> $(where $($where_clause)*)? {
518 type Error = Error;
519
520 fn try_from(robj: Robj) -> Result<Self> {
521 Self::try_from(&robj)
522 }
523 }
524 };
525}
526#[rustfmt::skip]
527impl_try_from_robj!(u8);
528impl_try_from_robj!(u16);
529impl_try_from_robj!(u32);
530impl_try_from_robj!(u64);
531impl_try_from_robj!(usize);
532
533impl_try_from_robj!(i8);
534impl_try_from_robj!(i16);
535impl_try_from_robj!(i32);
536impl_try_from_robj!(i64);
537impl_try_from_robj!(isize);
538
539impl_try_from_robj!(bool);
540
541impl_try_from_robj!(Rint);
542impl_try_from_robj!(Rfloat);
543impl_try_from_robj!(Rbool);
544impl_try_from_robj!(Rcplx);
545
546impl_try_from_robj!(f32);
547impl_try_from_robj!(f64);
548
549impl_try_from_robj!(Vec::<String>);
550impl_try_from_robj!(Vec::<Rint>);
551impl_try_from_robj!(Vec::<Rfloat>);
552impl_try_from_robj!(Vec::<Rbool>);
553impl_try_from_robj!(Vec::<Rcplx>);
554impl_try_from_robj!(Vec::<u8>);
555impl_try_from_robj!(Vec::<i32>);
556impl_try_from_robj!(Vec::<f64>);
557
558impl_try_from_robj!(&[Rint]);
559impl_try_from_robj!(&[Rfloat]);
560impl_try_from_robj!(&[Rbool]);
561impl_try_from_robj!(&[Rcplx]);
562impl_try_from_robj!(&[u8]);
563impl_try_from_robj!(&[i32]);
564impl_try_from_robj!(&[f64]);
565
566impl_try_from_robj!(&mut [Rint]);
567impl_try_from_robj!(&mut [Rfloat]);
568impl_try_from_robj!(&mut [Rbool]);
569impl_try_from_robj!(&mut [Rcplx]);
570impl_try_from_robj!(&mut [u8]);
571impl_try_from_robj!(&mut [i32]);
572impl_try_from_robj!(&mut [f64]);
573
574impl_try_from_robj!(&str);
575impl_try_from_robj!(String);
576
577impl_try_from_robj!(@generics<T> HashMap::<&str, T> where T: TryFrom<Robj, Error = error::Error>);
578impl_try_from_robj!(@generics<T> HashMap::<String,T> where T: TryFrom<Robj, Error = error::Error>);
579
580impl_try_from_robj!(HashMap::<&str, Robj>);
581impl_try_from_robj!(HashMap::<String, Robj>);
582
583impl TryFrom<&Robj> for Option<()> {
584 type Error = Error;
585
586 fn try_from(value: &Robj) -> Result<Self> {
587 if value.is_null() {
588 Ok(Some(()))
589 } else {
590 Err(Error::ExpectedNull(value.clone()))
591 }
592 }
593}
594
595impl TryFrom<Robj> for Option<()> {
596 type Error = Error;
597 fn try_from(robj: Robj) -> Result<Self> {
598 Self::try_from(&robj)
599 }
600}
601
602impl<T> TryFrom<&Robj> for HashMap<&str, T>
607where
608 T: TryFrom<Robj, Error = error::Error>,
609{
610 type Error = Error;
611
612 fn try_from(value: &Robj) -> Result<Self> {
613 let value: List = value.try_into()?;
614
615 let value = value
616 .iter()
617 .map(|(name, value)| -> Result<(&str, T)> { value.try_into().map(|x| (name, x)) })
618 .collect::<Result<HashMap<_, _>>>()?;
619
620 Ok(value)
621 }
622}
623
624impl<T> TryFrom<&Robj> for HashMap<String, T>
625where
626 T: TryFrom<Robj, Error = error::Error>,
627{
628 type Error = Error;
629 fn try_from(value: &Robj) -> Result<Self> {
630 let value: HashMap<&str, _> = value.try_into()?;
631 Ok(value.into_iter().map(|(k, v)| (k.to_string(), v)).collect())
632 }
633}
634
635macro_rules! impl_try_from_robj_for_arrays {
636 ($slice_type:ty) => {
637 impl<const N: usize> TryFrom<&Robj> for [$slice_type; N] {
638 type Error = Error;
639
640 fn try_from(value: &Robj) -> Result<Self> {
641 let value: &[$slice_type] = value.try_into()?;
642 if value.len() != N {
643 return Err(Error::ExpectedLength(N));
644 }
645 let value: Self = value
646 .try_into()
647 .map_err(|error| format!("{}", error).to_string())?;
648 Ok(value)
649 }
650 }
651
652 impl<const N: usize> TryFrom<Robj> for [$slice_type; N] {
655 type Error = Error;
656
657 fn try_from(robj: Robj) -> Result<Self> {
658 Self::try_from(&robj)
659 }
660 }
661
662 impl<const N: usize> TryFrom<&Robj> for Option<[$slice_type; N]> {
663 type Error = Error;
664
665 fn try_from(robj: &Robj) -> Result<Self> {
666 if robj.is_null() || robj.is_na() {
667 Ok(None)
668 } else {
669 Ok(Some(<[$slice_type; N]>::try_from(robj)?))
670 }
671 }
672 }
673
674 impl<const N: usize> TryFrom<Robj> for Option<[$slice_type; N]> {
675 type Error = Error;
676
677 fn try_from(robj: Robj) -> Result<Self> {
678 Self::try_from(&robj)
679 }
680 }
681 };
682}
683
684impl_try_from_robj_for_arrays!(Rint);
685impl_try_from_robj_for_arrays!(Rfloat);
686impl_try_from_robj_for_arrays!(Rbool);
687impl_try_from_robj_for_arrays!(Rcplx);
688impl_try_from_robj_for_arrays!(u8);
689impl_try_from_robj_for_arrays!(i32);
690impl_try_from_robj_for_arrays!(f64);
691
692impl<T0> TryFrom<&Robj> for (T0,)
698where
699 T0: for<'a> TryFrom<&'a Robj, Error = Error>,
700{
701 type Error = Error;
702
703 fn try_from(robj: &Robj) -> Result<Self> {
704 let list: List = robj.try_into()?;
705 if list.len() != 1 {
706 return Err(Error::ExpectedLength(1));
707 }
708 Ok(((&list.elt(0)?).try_into()?,))
709 }
710}
711
712impl<T0> TryFrom<Robj> for (T0,)
713where
714 T0: for<'a> TryFrom<&'a Robj, Error = Error>,
715{
716 type Error = Error;
717
718 fn try_from(robj: Robj) -> Result<Self> {
719 Self::try_from(&robj)
720 }
721}
722
723impl<T0> TryFrom<&Robj> for Option<(T0,)>
724where
725 T0: for<'a> TryFrom<&'a Robj, Error = Error>,
726{
727 type Error = Error;
728
729 fn try_from(robj: &Robj) -> Result<Self> {
730 if robj.is_null() || robj.is_na() {
731 Ok(None)
732 } else {
733 <(T0,)>::try_from(robj).map(Some)
734 }
735 }
736}
737
738impl<T0> TryFrom<Robj> for Option<(T0,)>
739where
740 T0: for<'a> TryFrom<&'a Robj, Error = Error>,
741{
742 type Error = Error;
743
744 fn try_from(robj: Robj) -> Result<Self> {
745 Self::try_from(&robj)
746 }
747}
748
749impl_try_from_robj_tuples!((2, 12));
750
751impl TryFrom<&Robj> for HashMap<&str, Robj> {
755 type Error = Error;
756
757 fn try_from(value: &Robj) -> Result<Self> {
758 let value: List = value.try_into()?;
759 Ok(value.into_iter().collect())
760 }
761}
762
763impl TryFrom<&Robj> for HashMap<String, Robj> {
764 type Error = Error;
765 fn try_from(value: &Robj) -> Result<Self> {
766 let value: HashMap<&str, _> = value.try_into()?;
767 Ok(value.into_iter().map(|(k, v)| (k.to_string(), v)).collect())
768 }
769}