use super::{Array, Scalar};
use nullable::Nullable;
use nullvec::NullVec;
macro_rules! add_array_conversion {
($t:ident, $klass:ident) => {
impl From<Vec<$t>> for Array {
fn from(values: Vec<$t>) -> Self {
Array::$klass(NullVec::new(values))
}
}
impl From<Array> for Vec<$t> {
fn from(values: Array) -> Self {
match values {
Array::$klass(vals) => vals.into(),
_ => panic!("Unable to convert to Vec")
}
}
}
impl From<Array> for Vec<Nullable<$t>> {
fn from(values: Array) -> Self {
match values {
Array::$klass(vals) => vals.into(),
_ => panic!("Unable to convert to Vec")
}
}
}
impl From<NullVec<$t>> for Array {
fn from(values: NullVec<$t>) -> Self {
Array::$klass(values)
}
}
impl From<Array> for NullVec<$t> {
fn from(values: Array) -> Self {
match values {
Array::$klass(vals) => vals,
_ => panic!("Unable to convert to Vec")
}
}
}
}
}
add_array_conversion!(i64, Int64Array);
add_array_conversion!(i32, Int32Array);
add_array_conversion!(i16, Int16Array);
add_array_conversion!(i8, Int8Array);
add_array_conversion!(isize, IsizeArray);
add_array_conversion!(u64, UInt64Array);
add_array_conversion!(u32, UInt32Array);
add_array_conversion!(u16, UInt16Array);
add_array_conversion!(u8, UInt8Array);
add_array_conversion!(usize, UsizeArray);
add_array_conversion!(f64, Float64Array);
add_array_conversion!(f32, Float32Array);
add_array_conversion!(bool, BoolArray);
add_array_conversion!(String, StringArray);
impl From<Vec<Scalar>> for Array {
fn from(values: Vec<Scalar>) -> Self {
assert!(values.len() > 0, "Unable to infer dtype");
match &values[0] {
&Scalar::i64(_) => {
values.iter().map(|ref x| x.as_i64()).collect::<NullVec<i64>>().into()
}
&Scalar::i32(_) => {
values.iter().map(|ref x| x.as_i32()).collect::<NullVec<i32>>().into()
}
&Scalar::i16(_) => {
values.iter().map(|ref x| x.as_i16()).collect::<NullVec<i16>>().into()
}
&Scalar::i8(_) => values.iter().map(|ref x| x.as_i8()).collect::<NullVec<i8>>().into(),
&Scalar::isize(_) => {
values.iter().map(|ref x| x.as_isize()).collect::<NullVec<isize>>().into()
}
&Scalar::u64(_) => {
values.iter().map(|ref x| x.as_u64()).collect::<NullVec<u64>>().into()
}
&Scalar::u32(_) => {
values.iter().map(|ref x| x.as_u32()).collect::<NullVec<u32>>().into()
}
&Scalar::u16(_) => {
values.iter().map(|ref x| x.as_u16()).collect::<NullVec<u16>>().into()
}
&Scalar::u8(_) => values.iter().map(|ref x| x.as_u8()).collect::<NullVec<u8>>().into(),
&Scalar::usize(_) => {
values.iter().map(|ref x| x.as_usize()).collect::<NullVec<usize>>().into()
}
&Scalar::f64(_) => {
values.iter().map(|ref x| x.as_f64()).collect::<NullVec<f64>>().into()
}
&Scalar::f32(_) => {
values.iter().map(|ref x| x.as_f32()).collect::<NullVec<f32>>().into()
}
&Scalar::bool(_) => {
values.iter().map(|ref x| x.as_bool()).collect::<NullVec<bool>>().into()
}
&Scalar::String(_) => {
values.iter().map(|ref x| x.as_str()).collect::<NullVec<String>>().into()
}
&Scalar::Null => panic!("unable to infer dtype"),
}
}
}
impl From<Array> for Vec<Scalar> {
fn from(values: Array) -> Self {
match values {
Array::Int64Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::i64(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::Int32Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::i32(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::Int16Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::i16(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::Int8Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::i8(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::IsizeArray(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::isize(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::UInt64Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::u64(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::UInt32Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::u32(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::UInt16Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::u16(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::UInt8Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::u8(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::UsizeArray(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::usize(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::Float64Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::f64(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::Float32Array(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::f32(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::BoolArray(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::bool(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
Array::StringArray(vals) => {
vals.into_iter()
.map(|x| match x {
Nullable::Value(val) => Scalar::String(val),
Nullable::Null => Scalar::Null,
})
.collect()
}
}
}
}
macro_rules! add_scalar_conversion {
($t:ident) => {
impl From<$t> for Scalar {
fn from(value: $t) -> Self {
Scalar::$t(value)
}
}
impl From<Nullable<$t>> for Scalar {
fn from(value: Nullable<$t>) -> Self {
match value {
Nullable::Null => Scalar::Null,
Nullable::Value(val) => Scalar::$t(val),
}
}
}
impl From<Scalar> for $t {
fn from(value: Scalar) -> Self {
match value {
Scalar::$t(val) => val,
_ => panic!("Unable to convert to primitive")
}
}
}
impl From<Scalar> for Nullable<$t> {
fn from(value: Scalar) -> Self {
match value {
Scalar::Null => Nullable::Null,
Scalar::$t(val) => Nullable::Value(val),
_ => panic!("Unable to convert to primitive")
}
}
}
}
}
add_scalar_conversion!(i64);
add_scalar_conversion!(i32);
add_scalar_conversion!(i16);
add_scalar_conversion!(i8);
add_scalar_conversion!(isize);
add_scalar_conversion!(u64);
add_scalar_conversion!(u32);
add_scalar_conversion!(u16);
add_scalar_conversion!(u8);
add_scalar_conversion!(usize);
add_scalar_conversion!(f64);
add_scalar_conversion!(f32);
add_scalar_conversion!(bool);
add_scalar_conversion!(String);
#[cfg(test)]
mod tests {
use super::super::{Array, Scalar};
use nullvec::NullVec;
#[test]
#[should_panic]
fn test_empty_scalar_to_array() {
let vals: Vec<Scalar> = vec![];
let _: Array = vals.into();
}
#[test]
fn test_i64_vec_to_array() {
let exp: Array = Array::Int64Array(NullVec::new(vec![1, 2]));
let vals: Vec<i64> = vec![1, 2];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::i64(1), Scalar::i64(2)];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<i64> = vec![1, 2];
let res = Array::from(vals);
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::i64(1), Scalar::i64(2)];
let res = Array::from(vals);
assert_eq!(res, exp);
}
#[test]
fn test_i64_array_to_vec() {
let exp: Vec<i64> = vec![1, 2];
let exps: Vec<Scalar> = vec![Scalar::i64(1), Scalar::i64(2)];
let vals = Array::Int64Array(NullVec::new(vec![1, 2]));
let res: Vec<i64> = vals.into();
assert_eq!(res, exp);
let vals = Array::Int64Array(NullVec::new(vec![1, 2]));
let res: Vec<Scalar> = vals.into();
assert_eq!(res, exps);
let vals = Array::Int64Array(NullVec::new(vec![1, 2]));
let res: Vec<i64> = Vec::from(vals);
assert_eq!(res, exp);
let vals = Array::Int64Array(NullVec::new(vec![1, 2]));
let res: Vec<Scalar> = Vec::from(vals);
assert_eq!(res, exps);
}
#[test]
fn test_usize_vec_to_array() {
let exp: Array = Array::UsizeArray(NullVec::new(vec![1, 2]));
let vals: Vec<usize> = vec![1, 2];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::usize(1), Scalar::usize(2)];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<usize> = vec![1, 2];
let res = Array::from(vals);
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::usize(1), Scalar::usize(2)];
let res = Array::from(vals);
assert_eq!(res, exp);
}
#[test]
fn test_usize_array_to_vec() {
let exp: Vec<usize> = vec![1, 2];
let exps: Vec<Scalar> = vec![Scalar::usize(1), Scalar::usize(2)];
let vals = Array::UsizeArray(NullVec::new(vec![1, 2]));
let res: Vec<usize> = vals.into();
assert_eq!(res, exp);
let vals = Array::UsizeArray(NullVec::new(vec![1, 2]));
let res: Vec<Scalar> = vals.into();
assert_eq!(res, exps);
let vals = Array::UsizeArray(NullVec::new(vec![1, 2]));
let res: Vec<usize> = Vec::from(vals);
assert_eq!(res, exp);
let vals = Array::UsizeArray(NullVec::new(vec![1, 2]));
let res: Vec<Scalar> = Vec::from(vals);
assert_eq!(res, exps);
}
#[test]
fn test_f64_vec_to_array() {
let exp: Array = Array::Float64Array(NullVec::new(vec![1.1, 2.2]));
let vals: Vec<f64> = vec![1.1, 2.2];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::f64(1.1), Scalar::f64(2.2)];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<f64> = vec![1.1, 2.2];
let res = Array::from(vals);
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::f64(1.1), Scalar::f64(2.2)];
let res = Array::from(vals);
assert_eq!(res, exp);
}
#[test]
fn test_f64_array_to_vec() {
let exp: Vec<f64> = vec![1.1, 2.2];
let exps: Vec<Scalar> = vec![Scalar::f64(1.1), Scalar::f64(2.2)];
let vals = Array::Float64Array(NullVec::new(vec![1.1, 2.2]));
let res: Vec<f64> = vals.into();
assert_eq!(res, exp);
let vals = Array::Float64Array(NullVec::new(vec![1.1, 2.2]));
let res: Vec<Scalar> = vals.into();
assert_eq!(res, exps);
let vals = Array::Float64Array(NullVec::new(vec![1.1, 2.2]));
let res: Vec<f64> = Vec::from(vals);
assert_eq!(res, exp);
let vals = Array::Float64Array(NullVec::new(vec![1.1, 2.2]));
let res: Vec<Scalar> = Vec::from(vals);
assert_eq!(res, exps);
}
#[test]
fn test_bool_vec_to_array() {
let exp: Array = Array::BoolArray(NullVec::new(vec![true, false]));
let vals: Vec<bool> = vec![true, false];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::bool(true), Scalar::bool(false)];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<bool> = vec![true, false];
let res = Array::from(vals);
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::bool(true), Scalar::bool(false)];
let res = Array::from(vals);
assert_eq!(res, exp);
}
#[test]
fn test_bool_array_to_vec() {
let exp: Vec<bool> = vec![true, false];
let exps: Vec<Scalar> = vec![Scalar::bool(true), Scalar::bool(false)];
let vals = Array::BoolArray(NullVec::new(vec![true, false]));
let res: Vec<bool> = vals.into();
assert_eq!(res, exp);
let vals = Array::BoolArray(NullVec::new(vec![true, false]));
let res: Vec<Scalar> = vals.into();
assert_eq!(res, exps);
let vals = Array::BoolArray(NullVec::new(vec![true, false]));
let res: Vec<bool> = Vec::from(vals);
assert_eq!(res, exp);
let vals = Array::BoolArray(NullVec::new(vec![true, false]));
let res: Vec<Scalar> = Vec::from(vals);
assert_eq!(res, exps);
}
#[test]
fn test_str_vec_to_array() {
let exp: Array = Array::StringArray(NullVec::new(vec!["a".to_string(), "b".to_string()]));
let vals: Vec<String> = vec!["a".to_string(), "b".to_string()];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::String("a".to_string()),
Scalar::String("b".to_string())];
let res: Array = vals.into();
assert_eq!(res, exp);
let vals: Vec<String> = vec!["a".to_string(), "b".to_string()];
let res = Array::from(vals);
assert_eq!(res, exp);
let vals: Vec<Scalar> = vec![Scalar::String("a".to_string()),
Scalar::String("b".to_string())];
let res = Array::from(vals);
assert_eq!(res, exp);
}
#[test]
fn test_str_array_to_vec() {
let exp: Vec<String> = vec!["a".to_string(), "b".to_string()];
let exps: Vec<Scalar> = vec![Scalar::String("a".to_string()),
Scalar::String("b".to_string())];
let vals = Array::StringArray(NullVec::new(vec!["a".to_string(), "b".to_string()]));
let res: Vec<String> = vals.into();
assert_eq!(res, exp);
let vals = Array::StringArray(NullVec::new(vec!["a".to_string(), "b".to_string()]));
let res: Vec<Scalar> = vals.into();
assert_eq!(res, exps);
let vals = Array::StringArray(NullVec::new(vec!["a".to_string(), "b".to_string()]));
let res: Vec<String> = Vec::from(vals);
assert_eq!(res, exp);
let vals = Array::StringArray(NullVec::new(vec!["a".to_string(), "b".to_string()]));
let res: Vec<Scalar> = Vec::from(vals);
assert_eq!(res, exps);
}
#[test]
fn test_i64_primitives_to_scalar() {
let exp = Scalar::i64(1);
let res: Scalar = 1i64.into();
assert_eq!(res, exp);
let res: Scalar = Scalar::from(1i64);
assert_eq!(res, exp);
}
#[test]
fn test_i64_scalar_to_primitives() {
let res: i64 = Scalar::i64(1).into();
assert_eq!(res, 1);
let res: i64 = i64::from(Scalar::i64(1));
assert_eq!(res, 1);
}
#[test]
fn test_f64_primitives_to_scalar() {
let exp = Scalar::f64(1.1);
let res: Scalar = (1.1).into();
assert_eq!(res, exp);
let res: Scalar = Scalar::from(1.1);
assert_eq!(res, exp);
}
#[test]
fn test_f64_scalar_to_primitives() {
let res: f64 = Scalar::f64(1.1).into();
assert_eq!(res, 1.1);
let res: f64 = f64::from(Scalar::f64(1.1));
assert_eq!(res, 1.1);
}
#[test]
fn test_bool_primitives_to_scalar() {
let exp = Scalar::bool(true);
let res: Scalar = true.into();
assert_eq!(res, exp);
let res: Scalar = Scalar::from(true);
assert_eq!(res, exp);
}
#[test]
fn test_bool_scalar_to_primitives() {
let res: bool = Scalar::bool(true).into();
assert_eq!(res, true);
let res: bool = bool::from(Scalar::bool(true));
assert_eq!(res, true);
}
#[test]
fn test_str_primitives_to_scalar() {
let exp = Scalar::String("a".to_string());
let res: Scalar = "a".to_string().into();
assert_eq!(res, exp);
let res: Scalar = Scalar::from("a".to_string());
assert_eq!(res, exp);
}
#[test]
fn test_str_scalar_to_primitives() {
let res: String = Scalar::String("a".to_string()).into();
assert_eq!(res, "a".to_string());
let res: String = String::from(Scalar::String("a".to_string()));
assert_eq!(res, "a".to_string());
}
}