Skip to content

Commit

Permalink
major revision: Removed FromRobj and IntoRobj
Browse files Browse the repository at this point in the history
  • Loading branch information
CGMossa committed Mar 4, 2024
1 parent d45dbd1 commit ae19ab7
Show file tree
Hide file tree
Showing 21 changed files with 146 additions and 460 deletions.
1 change: 0 additions & 1 deletion extendr-api/src/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use serde::de::{
Visitor,
};
use serde::forward_to_deserialize_any;
use std::convert::TryFrom;

/// Convert any R object to a Deserialize object.
pub fn from_robj<'de, T>(robj: &'de Robj) -> Result<T>
Expand Down
10 changes: 10 additions & 0 deletions extendr-api/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,13 @@ pub trait AsStrIter: GetSexp + Types + Length + Attributes + Rinternals {
}

impl AsStrIter for Robj {}

impl TryFrom<&Robj> for StrIter {
type Error = Error;

fn try_from(value: &Robj) -> Result<Self> {
value
.as_str_iter()
.ok_or_else(|| Error::ExpectedString(value.clone()))
}
}
2 changes: 1 addition & 1 deletion extendr-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ mod tests {
person.set_name("fred");
let robj = r!(person);
assert_eq!(robj.check_external_ptr_type::<Person>(), true);
let person2 = <&Person>::from_robj(&robj).unwrap();
let person2 = <&Person>::try_from(&robj).unwrap();
assert_eq!(person2.name(), "fred");
}
}
Expand Down
32 changes: 18 additions & 14 deletions extendr-api/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,17 @@ impl From<&Arg> for RArg {

impl From<Arg> for Robj {
fn from(val: Arg) -> Self {
List::from_values(&[r!(val.name), r!(val.arg_type)])
.into_robj()
.set_names(&["name", "arg_type"])
let mut robj: Robj = List::from_values(&[r!(val.name), r!(val.arg_type)])
.try_into()
.unwrap();
robj.set_names(&["name", "arg_type"])
.expect("From<Arg> failed")
}
}

impl From<Func> for Robj {
fn from(val: Func) -> Self {
List::from_values(&[
let mut robj: Robj = List::from_values(&[
r!(val.doc),
r!(val.rust_name),
r!(val.mod_name),
Expand All @@ -94,8 +95,9 @@ impl From<Func> for Robj {
r!(val.return_type),
r!(val.hidden),
])
.into_robj()
.set_names(&[
.try_into()
.unwrap();
robj.set_names(&[
"doc",
"rust_name",
"mod_name",
Expand All @@ -110,27 +112,29 @@ impl From<Func> for Robj {

impl From<Impl> for Robj {
fn from(val: Impl) -> Self {
List::from_values(&[
let mut robj: Robj = List::from_values(&[
r!(val.doc),
r!(val.name),
r!(List::from_values(val.methods)),
])
.into_robj()
.set_names(&["doc", "name", "methods"])
.expect("From<Impl> failed")
.try_into()
.unwrap();
robj.set_names(&["doc", "name", "methods"])
.expect("From<Impl> failed")
}
}

impl From<Metadata> for Robj {
fn from(val: Metadata) -> Self {
List::from_values(&[
let mut robj: Robj = List::from_values(&[
r!(val.name),
r!(List::from_values(val.functions)),
r!(List::from_values(val.impls)),
])
.into_robj()
.set_names(&["name", "functions", "impls"])
.expect("From<Metadata> failed")
.try_into()
.unwrap();
robj.set_names(&["name", "functions", "impls"])
.expect("From<Metadata> failed")
}
}

Expand Down
1 change: 0 additions & 1 deletion extendr-api/src/optional/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ fn type_aware_sum(input : Either<Integers, Doubles>) -> Either<Rint, Rfloat> {
```
*/
use crate::prelude::*;
use crate::{Error, Robj};

impl<'a, L, R> TryFrom<&'a Robj> for Either<L, R>
where
Expand Down
35 changes: 8 additions & 27 deletions extendr-api/src/optional/ndarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,11 @@ For all array uses in Rust, refer to the [`ndarray::ArrayBase`] documentation, w
*/
#[doc(hidden)]
use ndarray::prelude::*;
use ndarray::{Data, ShapeBuilder};
use ndarray::Data;

use crate::prelude::{c64, dim_symbol, Rcplx, Rfloat, Rint};
use crate::*;

impl<'a, T> FromRobj<'a> for ArrayView1<'a, T>
where
Robj: AsTypedSlice<'a, T>,
{
/// Convert an R object to a `ndarray` ArrayView1.
fn from_robj(robj: &'a Robj) -> std::result::Result<Self, &'static str> {
if let Some(v) = robj.as_typed_slice() {
Ok(ArrayView1::<'a, T>::from(v))
} else {
Err("Not a vector of the correct type.")
}
}
}

macro_rules! make_array_view_1 {
($type: ty, $error_fn: expr) => {
impl<'a> TryFrom<&'_ Robj> for ArrayView1<'a, $type> {
Expand All @@ -101,13 +87,6 @@ macro_rules! make_array_view_1 {

macro_rules! make_array_view_2 {
($type: ty, $error_str: expr, $error_fn: expr) => {
impl<'a> FromRobj<'a> for ArrayView2<'a, $type> {
/// Convert an R object to a `ndarray` ArrayView2.
fn from_robj(robj: &'a Robj) -> std::result::Result<Self, &'static str> {
<ArrayView2<'a, $type>>::try_from(robj).map_err(|_| $error_str)
}
}

impl<'a> TryFrom<&'_ Robj> for ArrayView2<'a, $type> {
type Error = crate::Error;
fn try_from(robj: &Robj) -> Result<Self> {
Expand Down Expand Up @@ -216,7 +195,7 @@ where
#[cfg(test)]
mod test {
use super::*;
use crate::FromRobj;
use crate as extendr_api;
use ndarray::array;
use rstest::rstest;

Expand Down Expand Up @@ -252,19 +231,21 @@ mod test {
"matrix(c(T, T, T, T, F, F, F, F), ncol=2, nrow=4)",
<Array2<Rbool>>::from_shape_vec((4, 2).f(), vec![true.into(), true.into(), true.into(), true.into(), false.into(), false.into(), false.into(), false.into()]).unwrap()
)]
fn test_from_robj<DataType, DimType>(
fn test_from_robj<DataType, DimType, Error>(
#[case] left: &'static str,
#[case] right: ArrayBase<DataType, DimType>,
) where
DataType: Data,
for<'a> ArrayView<'a, <DataType as ndarray::RawData>::Elem, DimType>: FromRobj<'a>,
for<'a> ArrayView<'a, <DataType as ndarray::RawData>::Elem, DimType>:
TryFrom<&'a Robj, Error = Error>,
DimType: Dimension,
Error: std::fmt::Debug,
<DataType as ndarray::RawData>::Elem: PartialEq + std::fmt::Debug,
{
// Tests for the R → Rust conversion
test! {
let left_robj = eval_string(left).unwrap();
let left_array = <ArrayView<DataType::Elem, DimType>>::from_robj(&left_robj).unwrap();
let left_array = <ArrayView<DataType::Elem, DimType>>::try_from(&left_robj).unwrap();
assert_eq!( left_array, right );
}
}
Expand Down Expand Up @@ -337,7 +318,7 @@ mod test {
];
for rval in rvals {
let rval = rval.unwrap();
let rust_arr= <ArrayView2<i32>>::from_robj(&rval).unwrap();
let rust_arr= <ArrayView2<i32>>::try_from(&rval).unwrap();
let r_arr: Robj = (&rust_arr).try_into().unwrap();
assert_eq!(
rval,
Expand Down
8 changes: 4 additions & 4 deletions extendr-api/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! using deprecated features.
pub use super::{
print_r_error, print_r_output, CanBeNA, FromRobj, Rtype, FALSE, NA_INTEGER, NA_LOGICAL,
NA_REAL, NA_STRING, NULL, TRUE,
print_r_error, print_r_output, CanBeNA, Rtype, FALSE, NA_INTEGER, NA_LOGICAL, NA_REAL,
NA_STRING, NULL, TRUE,
};

pub use super::na::*;
Expand Down Expand Up @@ -49,8 +49,8 @@ pub use super::wrapper::s4::S4;
pub use super::wrapper::{Conversions, MatrixConversions};

pub use super::robj::{
AsStrIter, Attributes, Eval, GetSexp, IntoRobj, Length, Operators, Rinternals, Robj,
RobjItertools, Slices, Types,
AsStrIter, Attributes, Eval, GetSexp, Length, Operators, Rinternals, Robj, RobjItertools,
Slices, Types,
};

pub use super::thread_safety::{catch_r_error, handle_panic, single_threaded, throw_r_error};
Expand Down
Loading

0 comments on commit ae19ab7

Please sign in to comment.