Skip to content

Commit

Permalink
Add error contexts to OuterSequence builder contruction
Browse files Browse the repository at this point in the history
  • Loading branch information
chmp committed Sep 1, 2024
1 parent 45b1b05 commit 218586b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 43 deletions.
12 changes: 2 additions & 10 deletions serde_arrow/src/internal/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,9 @@ pub trait Context {
fn annotations(&self) -> BTreeMap<String, String>;
}

pub struct StaticContext(BTreeMap<String, String>);

impl StaticContext {
pub fn from_context<C: Context>(context: &C) -> Self {
Self(context.annotations())
}
}

impl Context for StaticContext {
impl Context for BTreeMap<String, String> {
fn annotations(&self) -> BTreeMap<String, String> {
self.0.clone()
self.clone()
}
}

Expand Down
11 changes: 3 additions & 8 deletions serde_arrow/src/internal/serialization/list_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,13 @@ pub struct ListBuilder<O> {
}

impl<O: Offset> ListBuilder<O> {
pub fn new(
path: String,
meta: FieldMeta,
element: ArrayBuilder,
is_nullable: bool,
) -> Result<Self> {
Ok(Self {
pub fn new(path: String, meta: FieldMeta, element: ArrayBuilder, is_nullable: bool) -> Self {
Self {
path,
meta,
element: Box::new(element),
offsets: OffsetsArray::new(is_nullable),
})
}
}

pub fn take_self(&mut self) -> Self {
Expand Down
44 changes: 24 additions & 20 deletions serde_arrow/src/internal/serialization/outer_sequence_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use serde::Serialize;

use crate::internal::{
arrow::{DataType, Field, TimeUnit},
error::{fail, Context, Result},
error::{fail, Context, ContextSupport, Result},
schema::{get_strategy_from_metadata, SerdeArrowSchema, Strategy},
serialization::{
binary_builder::BinaryBuilder, duration_builder::DurationBuilder,
fixed_size_binary_builder::FixedSizeBinaryBuilder,
fixed_size_list_builder::FixedSizeListBuilder,
},
utils::{meta_from_field, Mut},
utils::{btree_map, meta_from_field, Mut},
};

use super::{
Expand Down Expand Up @@ -123,6 +123,7 @@ fn build_struct(path: String, struct_fields: &[Field], nullable: bool) -> Result

fn build_builder(path: String, field: &Field) -> Result<ArrayBuilder> {
use {ArrayBuilder as A, DataType as T};
let ctx: BTreeMap<String, String> = btree_map!("path" => path.clone());

let builder = match &field.data_type {
T::Null => match get_strategy_from_metadata(&field.metadata)? {
Expand Down Expand Up @@ -151,18 +152,18 @@ fn build_builder(path: String, field: &Field) -> Result<ArrayBuilder> {
T::Timestamp(unit, tz) => A::Date64(Date64Builder::new(
path,
Some((*unit, tz.clone())),
is_utc_tz(tz.as_deref())?,
is_utc_tz(tz.as_deref()).ctx(&ctx)?,
field.nullable,
)),
T::Time32(unit) => {
if !matches!(unit, TimeUnit::Second | TimeUnit::Millisecond) {
fail!("Only timestamps with second or millisecond unit are supported");
fail!(in ctx, "Time32 only supports second or millisecond resolutions");
}
A::Time32(TimeBuilder::new(path, *unit, field.nullable))
}
T::Time64(unit) => {
if !matches!(unit, TimeUnit::Nanosecond | TimeUnit::Microsecond) {
fail!("Only timestamps with nanosecond or microsecond unit are supported");
fail!(in ctx, "Time64 only supports nanosecond or microsecond resolutions");
}
A::Time64(TimeBuilder::new(path, *unit, field.nullable))
}
Expand All @@ -182,7 +183,7 @@ fn build_builder(path: String, field: &Field) -> Result<ArrayBuilder> {
meta_from_field(*child.clone()),
build_builder(child_path, child.as_ref())?,
field.nullable,
)?)
))
}
T::LargeList(child) => {
let child_path = format!("{path}.{child_name}", child_name = ChildName(&child.name));
Expand All @@ -191,36 +192,39 @@ fn build_builder(path: String, field: &Field) -> Result<ArrayBuilder> {
meta_from_field(*child.clone()),
build_builder(child_path, child.as_ref())?,
field.nullable,
)?)
))
}
T::FixedSizeList(child, n) => {
let child_path = format!("{path}.{child_name}", child_name = ChildName(&child.name));
let n = usize::try_from(*n).ctx(&ctx)?;
A::FixedSizedList(FixedSizeListBuilder::new(
path,
meta_from_field(*child.clone()),
build_builder(child_path, child.as_ref())?,
(*n).try_into()?,
n,
field.nullable,
))
}
T::Binary => A::Binary(BinaryBuilder::new(path, field.nullable)),
T::LargeBinary => A::LargeBinary(BinaryBuilder::new(path, field.nullable)),
T::FixedSizeBinary(n) => A::FixedSizeBinary(FixedSizeBinaryBuilder::new(
path,
(*n).try_into()?,
field.nullable,
)),
T::FixedSizeBinary(n) => {
let n = usize::try_from(*n).ctx(&ctx)?;
A::FixedSizeBinary(FixedSizeBinaryBuilder::new(path, n, field.nullable))
}
T::Map(entry_field, _) => {
let child_path = format!(
"{path}.{child_name}",
child_name = ChildName(&entry_field.name)
);
A::Map(MapBuilder::new(
path,
meta_from_field(*entry_field.clone()),
build_builder(child_path, entry_field.as_ref())?,
field.nullable,
)?)
A::Map(
MapBuilder::new(
path,
meta_from_field(*entry_field.clone()),
build_builder(child_path, entry_field.as_ref())?,
field.nullable,
)
.ctx(&ctx)?,
)
}
T::Struct(children) => A::Struct(build_struct(path, children, field.nullable)?),
T::Dictionary(key, value, _) => {
Expand Down Expand Up @@ -250,7 +254,7 @@ fn build_builder(path: String, field: &Field) -> Result<ArrayBuilder> {
let mut fields = Vec::new();
for (idx, (type_id, field)) in union_fields.iter().enumerate() {
if usize::try_from(*type_id) != Ok(idx) {
fail!("non consecutive type ids are not supported");
fail!(in ctx, "Union with non consecutive type ids are not supported");
}
let field_path =
format!("{path}.{field_name}", field_name = ChildName(&field.name));
Expand Down
10 changes: 5 additions & 5 deletions serde_arrow/src/internal/serialization/union_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::BTreeMap;

use crate::internal::{
arrow::{Array, DenseUnionArray, FieldMeta},
error::{fail, Context, ContextSupport, Result, StaticContext},
error::{fail, Context, ContextSupport, Result},
utils::{btree_map, Mut},
};

Expand Down Expand Up @@ -88,7 +88,7 @@ impl SimpleSerializer for UnionBuilder {
variant_index: u32,
_: &'static str,
) -> Result<()> {
let ctx = StaticContext::from_context(self);
let ctx = self.annotations();
self.serialize_variant(variant_index)
.ctx(&ctx)?
.serialize_unit()
Expand All @@ -101,7 +101,7 @@ impl SimpleSerializer for UnionBuilder {
_: &'static str,
value: &V,
) -> Result<()> {
let ctx = StaticContext::from_context(self);
let ctx = self.annotations();
let variant_builder = self.serialize_variant(variant_index).ctx(&ctx)?;
value.serialize(Mut(variant_builder))
}
Expand All @@ -113,7 +113,7 @@ impl SimpleSerializer for UnionBuilder {
variant: &'static str,
len: usize,
) -> Result<&'this mut ArrayBuilder> {
let ctx = StaticContext::from_context(self);
let ctx = self.annotations();
let variant_builder = self.serialize_variant(variant_index).ctx(&ctx)?;
variant_builder.serialize_struct_start(variant, len)?;
Ok(variant_builder)
Expand All @@ -126,7 +126,7 @@ impl SimpleSerializer for UnionBuilder {
variant: &'static str,
len: usize,
) -> Result<&'this mut ArrayBuilder> {
let ctx = StaticContext::from_context(self);
let ctx = self.annotations();
let variant_builder = self.serialize_variant(variant_index).ctx(&ctx)?;
variant_builder.serialize_tuple_struct_start(variant, len)?;
Ok(variant_builder)
Expand Down

0 comments on commit 218586b

Please sign in to comment.