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<'a> From<Vec<&'a str>> for Array {
fn from(values: Vec<&str>) -> Self {
let string: Vec<String> = values.iter().map(|x| x.to_string()).collect();
string.into()
}
}
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")
}
}
}
}
}
macro_rules! add_scalar_conversion_str {
($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 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_str!(String);
impl<'a> From<&'a str> for Scalar {
fn from(value: &'a str) -> Self {
if value == "Null" {
Scalar::Null
} else {
value
.parse()
.map(Scalar::i64)
.or_else(|_| {
value.parse().map(Scalar::f64).or_else(|_| {
value.parse().map(Scalar::bool)
})
})
.unwrap_or_else(|_| Scalar::String(value.to_string()))
}
}
}
impl From<Scalar> for String {
fn from(value: Scalar) -> Self {
match value {
Scalar::Null => "Null".to_string(),
Scalar::String(val) => val,
_ => value.to_string(),
}
}
}