use crate::{ArrowError, Field, FieldRef};
use std::ops::Deref;
use std::sync::Arc;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct Fields(Arc<[FieldRef]>);
impl std::fmt::Debug for Fields {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.as_ref().fmt(f)
}
}
impl Fields {
pub fn empty() -> Self {
Self(Arc::new([]))
}
pub fn size(&self) -> usize {
self.iter()
.map(|field| field.size() + std::mem::size_of::<FieldRef>())
.sum()
}
pub fn find(&self, name: &str) -> Option<(usize, &FieldRef)> {
self.0.iter().enumerate().find(|(_, b)| b.name() == name)
}
pub fn contains(&self, other: &Fields) -> bool {
if Arc::ptr_eq(&self.0, &other.0) {
return true;
}
self.len() == other.len()
&& self
.iter()
.zip(other.iter())
.all(|(a, b)| Arc::ptr_eq(a, b) || a.contains(b))
}
}
impl Default for Fields {
fn default() -> Self {
Self::empty()
}
}
impl FromIterator<Field> for Fields {
fn from_iter<T: IntoIterator<Item = Field>>(iter: T) -> Self {
iter.into_iter().map(Arc::new).collect()
}
}
impl FromIterator<FieldRef> for Fields {
fn from_iter<T: IntoIterator<Item = FieldRef>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
impl From<Vec<Field>> for Fields {
fn from(value: Vec<Field>) -> Self {
value.into_iter().collect()
}
}
impl From<Vec<FieldRef>> for Fields {
fn from(value: Vec<FieldRef>) -> Self {
Self(value.into())
}
}
impl From<&[FieldRef]> for Fields {
fn from(value: &[FieldRef]) -> Self {
Self(value.into())
}
}
impl<const N: usize> From<[FieldRef; N]> for Fields {
fn from(value: [FieldRef; N]) -> Self {
Self(Arc::new(value))
}
}
impl Deref for Fields {
type Target = [FieldRef];
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl<'a> IntoIterator for &'a Fields {
type Item = &'a FieldRef;
type IntoIter = std::slice::Iter<'a, FieldRef>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct UnionFields(Arc<[(i8, FieldRef)]>);
impl std::fmt::Debug for UnionFields {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.as_ref().fmt(f)
}
}
impl UnionFields {
pub fn empty() -> Self {
Self(Arc::from([]))
}
pub fn new<F, T>(type_ids: T, fields: F) -> Self
where
F: IntoIterator,
F::Item: Into<FieldRef>,
T: IntoIterator<Item = i8>,
{
let fields = fields.into_iter().map(Into::into);
let mut set = 0_u128;
type_ids
.into_iter()
.map(|idx| {
let mask = 1_u128 << idx;
if (set & mask) != 0 {
panic!("duplicate type id: {}", idx);
} else {
set |= mask;
}
idx
})
.zip(fields)
.collect()
}
pub fn size(&self) -> usize {
self.iter()
.map(|(_, field)| field.size() + std::mem::size_of::<(i8, FieldRef)>())
.sum()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (i8, &FieldRef)> + '_ {
self.0.iter().map(|(id, f)| (*id, f))
}
pub(crate) fn try_merge(&mut self, other: &Self) -> Result<(), ArrowError> {
let mut output: Vec<_> = self.iter().map(|(id, f)| (id, f.clone())).collect();
for (field_type_id, from_field) in other.iter() {
let mut is_new_field = true;
for (self_type_id, self_field) in output.iter_mut() {
if from_field == self_field {
if *self_type_id != field_type_id {
return Err(ArrowError::SchemaError(
format!("Fail to merge schema field '{}' because the self_type_id = {} does not equal field_type_id = {}",
self_field.name(), self_type_id, field_type_id)
));
}
is_new_field = false;
break;
}
}
if is_new_field {
output.push((field_type_id, from_field.clone()))
}
}
*self = output.into_iter().collect();
Ok(())
}
}
impl FromIterator<(i8, FieldRef)> for UnionFields {
fn from_iter<T: IntoIterator<Item = (i8, FieldRef)>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}