Blanket implementation `From<Option<T>> where T: Into<Robj>`
It would be nice to have a blanket implementation
impl<T> From<Option<T>> for Robj
where
T: Into<Robj>,
{
fn from(value: Option<T>) -> Self {
if let Some(some) = value {
some.into()
} else {
().into()
}
}
}
This is not possible as this clashes with ToVectorValue implementations for Option<...>. These return the correct NA value for the type instead of NULL.
Related: #308.
Rust's implementations have to be precise which may relax in the future to allow some overlap.
There is a blanket Nullable<T> which is less likely to clash with other implemementations.
As we have it Option<T> is for NAs and Nullable<T> is for NULLs.
Rust's implementations have to be precise which may relax in the future to allow some overlap.
I don't understand this. The code I posted above works, as long as we remove all implementations of ToVectorValue for Option<...>. However, then vec![Some(12), None] will be converted to R as c(12L, NULL) instead of c(12L, NA).
Yes. This is true. The current interpretation of Option is NA rather than NULL.
Now we have Rint and Rfloat we might drop this as it is counter intuitive, we might expect
Option to be the same as Nullable.
Perhaps that now we have the scalar types Rint and Rfloat that handle NAs, we should reserve
Option for NULL instead of NA and drop Nullable. Would this make more sense?
This sounds reasonable to me. But we probably need a complete implementation of scalar types first. Which ones are still missing? Only Rbool?
Rbool, Rcomplex at least. Ideally, we should also make Rbyte.
We should revise ToVectorValue
I agree, I spent a lot of time trying to understand how it works while working on Integers & Doubles.