Skip to content

Commit

Permalink
Add a trait SchemaLike for schema construction
Browse files Browse the repository at this point in the history
  • Loading branch information
chmp committed Nov 2, 2023
1 parent 1f0242f commit 91973de
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 157 deletions.
10 changes: 6 additions & 4 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Breaking changes:

Improvements:

- Simpler and streamlined API
- Simpler and streamlined API (`to_arrow` / `from_arrow` and `to_arrow2` /
`from_arrow2`)
- Add `SchemaLike` trait to support direct construction of arrow / arrow2 fields
- Add type based tracing to allow schema tracing without samples
(`SerdeArrowSchema::form_type()`)
(`SchemaLike::form_type()`)
- Allow to build schema objects from serializable objects, e.g.,
`serde_json::Value` (`SerdeArrow::from_value()`)
`serde_json::Value` (`SchemaLike::from_value()`)
- Add support for `arrow=47` and `arrow=48`

Deprecations (see the documentation of deprecated items for how to migratie):
Expand All @@ -26,7 +28,7 @@ Deprecations (see the documentation of deprecated items for how to migratie):
- Deprecate `serialize_into_arrays`, `deserialize_from_arrays` methods in favor of
`to_arrow` / `to_arrow2` and `from_arrow` / `from_arrow2`
- Deprecate `serialize_into_fields` methods in favor of
`SerdeArrowSchema::from_samples`
`SchemaLike::from_samples`
- Deprecated single item methods in favor of using the `Items` and `Item`
wrappers

Expand Down
2 changes: 1 addition & 1 deletion example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn main() -> Result<(), PanicOnError> {
},
];

use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
use serde_arrow::schema::{SchemaLike, SerdeArrowSchema, TracingOptions};

let fields: Vec<Field> =
SerdeArrowSchema::from_samples(&examples, TracingOptions::default().guess_dates(true))?
Expand Down
2 changes: 1 addition & 1 deletion serde_arrow/benches/groups/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ macro_rules! define_benchmark {
)?
) => {
pub fn benchmark_serialize(c: &mut criterion::Criterion) {
use serde_arrow::schema::SerdeArrowSchema;
use serde_arrow::schema::{SerdeArrowSchema, SchemaLike};

for n in [$($n),*] {
let mut group = c.benchmark_group(format!("{}_serialize({})", stringify!($name), n));
Expand Down
45 changes: 25 additions & 20 deletions serde_arrow/src/arrow2_impl/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
},
};

/// Build arrow2 arrays record by record (*requires one of the `arrow2-*`
/// Build arrow2 arrays record by record (*requires one of the `arrow2-*`
/// features*)
///
/// The given items should be records (e.g., structs). To serialize items
Expand Down Expand Up @@ -115,8 +115,10 @@ impl Arrow2Builder {
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow2;
/// use arrow2::datatypes::Field;
/// use serde::{Serialize, Deserialize};
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Serialize, Deserialize)]
/// struct Record {
Expand All @@ -129,8 +131,7 @@ impl Arrow2Builder {
/// // ...
/// ];
///
/// let fields = SerdeArrowSchema::from_type::<Record>(TracingOptions::default())?.
/// to_arrow2_fields()?;
/// let fields = Vec::<Field>::from_type::<Record>(TracingOptions::default())?;
///
/// let arrays = serde_arrow::to_arrow2(&fields, &items)?;
/// #
Expand Down Expand Up @@ -164,17 +165,18 @@ where
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow2;
/// use arrow2::datatypes::Field;
/// use serde::{Deserialize, Serialize};
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Deserialize, Serialize)]
/// struct Record {
/// a: Option<f32>,
/// b: u64,
/// }
///
/// let fields = SerdeArrowSchema::from_type::<Record>(TracingOptions::default())?
/// .to_arrow2_fields()?;
/// let fields = Vec::<Field>::from_type::<Record>(TracingOptions::default())?;
/// # let items = &[Record { a: Some(1.0), b: 2}];
/// # let arrays = serde_arrow::to_arrow2(&fields, &items).unwrap();
/// #
Expand Down Expand Up @@ -222,13 +224,15 @@ where
}

/// Replaced by
/// [`SerdeArrowSchema::from_samples`][crate::schema::SerdeArrowSchema::from_samples]
/// [`SchemaLike::from_samples`][crate::schema::SchemaLike::from_samples]
/// (*[example][serialize_into_fields]*)
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow2;
/// use arrow2::datatypes::Field;
/// use serde::Serialize;
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Serialize)]
/// struct Record {
Expand All @@ -237,8 +241,7 @@ where
/// }
///
/// let samples = [Record { a: 1, b: 2.0 }, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&samples, TracingOptions::default())?
/// .to_arrow2_fields()?;
/// let fields = Vec::<Field>::from_samples(&samples, TracingOptions::default())?;
/// #
/// # drop(fields);
/// # Ok(())
Expand Down Expand Up @@ -276,19 +279,20 @@ where
}

/// Replaced by
/// [`SerdeArrowSchema::from_samples`][crate::schema::SerdeArrowSchema::from_samples]
/// and [`Items`][crate::utils::Items] (*[example][serialize_into_field]*)
/// [`SchemaLike::from_samples`][crate::schema::SchemaLike::from_samples] and
/// [`Items`][crate::utils::Items] (*[example][serialize_into_field]*)
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow2;
/// use arrow2::datatypes::Field;
/// use serde_arrow::{
/// schema::{SerdeArrowSchema, TracingOptions},
/// schema::{SchemaLike, TracingOptions},
/// utils::Items,
/// };
///
/// let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// .to_arrow2_fields()?;
/// let fields = Vec::<Field>::from_samples(&Items(&samples), TracingOptions::default())?;
/// #
/// # drop(fields);
/// # Ok(())
Expand All @@ -310,14 +314,15 @@ where
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow2;
/// use arrow2::datatypes::Field;
/// use serde_arrow::{
/// schema::{SerdeArrowSchema, TracingOptions},
/// schema::{SchemaLike, TracingOptions},
/// utils::Items,
/// };
///
/// let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// .to_arrow2_fields()?;
/// let fields = Vec::<Field>::from_samples(&Items(&samples), TracingOptions::default())?;
///
/// let arrays = serde_arrow::to_arrow2(&fields, &Items(&samples))?;
/// #
Expand Down Expand Up @@ -346,7 +351,7 @@ where
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// # use serde_arrow::schema::{SerdeArrowSchema, SchemaLike, TracingOptions};
/// # let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// # let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// # .to_arrow2_fields()?;
Expand Down
29 changes: 26 additions & 3 deletions serde_arrow/src/arrow2_impl/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
internal::{
error::{error, fail, Error, Result},
schema::{
GenericDataType, GenericField, GenericTimeUnit, SerdeArrowSchema, Strategy,
STRATEGY_KEY,
GenericDataType, GenericField, GenericTimeUnit, SchemaLike, Sealed, SerdeArrowSchema,
Strategy, STRATEGY_KEY,
},
},
};
Expand All @@ -26,7 +26,7 @@ impl SerdeArrowSchema {
///
/// ```rust
/// # fn main() -> serde_arrow::_impl::PanicOnError<()> {
/// # use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// # use serde_arrow::schema::{SerdeArrowSchema, SchemaLike, TracingOptions};
/// # #[derive(serde::Deserialize)]
/// # struct Item { a: u32 }
/// # let schema = SerdeArrowSchema::from_type::<Item>(TracingOptions::default()).unwrap();
Expand Down Expand Up @@ -55,6 +55,29 @@ impl TryFrom<SerdeArrowSchema> for Vec<Field> {
}
}

impl Sealed for Vec<Field> {}

/// Schema support for `Vec<arrow2::datatype::Field>` (*requires one of the
/// `arrow2-*` features*)
impl SchemaLike for Vec<Field> {
fn from_value<T: serde::Serialize>(value: &T) -> Result<Self> {
SerdeArrowSchema::from_value(value)?.to_arrow2_fields()
}

fn from_type<'de, T: serde::Deserialize<'de>>(
options: crate::schema::TracingOptions,
) -> Result<Self> {
SerdeArrowSchema::from_type::<T>(options)?.to_arrow2_fields()
}

fn from_samples<T: serde::Serialize>(
samples: &T,
options: crate::schema::TracingOptions,
) -> Result<Self> {
SerdeArrowSchema::from_samples(samples, options)?.to_arrow2_fields()
}
}

impl TryFrom<&Field> for GenericField {
type Error = Error;

Expand Down
43 changes: 24 additions & 19 deletions serde_arrow/src/arrow_impl/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ impl ArrowBuilder {
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow;
/// use arrow::datatypes::Field;
/// use serde::{Serialize, Deserialize};
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Serialize, Deserialize)]
/// struct Record {
Expand All @@ -131,8 +133,7 @@ impl ArrowBuilder {
/// // ...
/// ];
///
/// let fields = SerdeArrowSchema::from_type::<Record>(TracingOptions::default())?
/// .to_arrow_fields()?;
/// let fields = Vec::<Field>::from_type::<Record>(TracingOptions::default())?;
/// let arrays = serde_arrow::to_arrow(&fields, &items)?;
/// #
/// # assert_eq!(arrays.len(), 2);
Expand Down Expand Up @@ -161,8 +162,10 @@ pub fn to_arrow<T: Serialize + ?Sized>(fields: &[Field], items: &T) -> Result<Ve
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow;
/// use arrow::datatypes::Field;
/// use serde::{Deserialize, Serialize};
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Deserialize, Serialize)]
/// struct Record {
Expand All @@ -171,8 +174,7 @@ pub fn to_arrow<T: Serialize + ?Sized>(fields: &[Field], items: &T) -> Result<Ve
/// }
///
/// // provide an example record to get the field information
/// let fields = SerdeArrowSchema::from_type::<Record>(TracingOptions::default())?
/// .to_arrow_fields()?;
/// let fields = Vec::<Field>::from_type::<Record>(TracingOptions::default())?;
/// # let items = &[Record { a: Some(1.0), b: 2}];
/// # let arrays = serde_arrow::to_arrow(&fields, &items).unwrap();
/// #
Expand Down Expand Up @@ -220,13 +222,15 @@ where
}

/// Replaced by
/// [`SerdeArrowSchema::from_samples`][crate::schema::SerdeArrowSchema::from_samples]
/// [`SchemaLike::from_samples`][crate::schema::SchemaLike::from_samples]
/// (*[example][serialize_into_fields]*)
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow;
/// use arrow::datatypes::Field;
/// use serde::Serialize;
/// use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// use serde_arrow::schema::{SchemaLike, TracingOptions};
///
/// ##[derive(Serialize)]
/// struct Record {
Expand All @@ -235,8 +239,7 @@ where
/// }
///
/// let samples = [Record { a: 1, b: 2.0 }, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&samples, TracingOptions::default())?
/// .to_arrow_fields()?;
/// let fields = Vec::<Field>::from_samples(&samples, TracingOptions::default())?;
/// #
/// # drop(fields);
/// # Ok(())
Expand All @@ -255,19 +258,20 @@ where
}

/// Replaced by
/// [`SerdeArrowSchema::from_samples`][crate::schema::SerdeArrowSchema::from_samples]
/// and [`Items`][crate::utils::Items] (*[example][serialize_into_field]*)
/// [`SchemaLike::from_samples`][crate::schema::SchemaLike::from_samples] and
/// [`Items`][crate::utils::Items] (*[example][serialize_into_field]*)
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow;
/// use arrow::datatypes::Field;
/// use serde_arrow::{
/// schema::{SerdeArrowSchema, TracingOptions},
/// schema::{SchemaLike, TracingOptions},
/// utils::Items,
/// };
///
/// let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// .to_arrow_fields()?;
/// let fields = Vec::<Field>::from_samples(&Items(&samples), TracingOptions::default())?;
/// #
/// # drop(fields);
/// # Ok(())
Expand Down Expand Up @@ -309,14 +313,15 @@ where
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::_impl::arrow;
/// use arrow::datatypes::Field;
/// use serde_arrow::{
/// schema::{SerdeArrowSchema, TracingOptions},
/// schema::{SchemaLike, TracingOptions},
/// utils::Items,
/// };
///
/// let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// .to_arrow_fields()?;
/// let fields = Vec::<Field>::from_samples(&Items(&samples), TracingOptions::default())?;
///
/// let arrays = serde_arrow::to_arrow(&fields, &Items(&samples))?;
/// #
Expand Down Expand Up @@ -345,7 +350,7 @@ where
///
/// ```rust
/// # fn main() -> serde_arrow::Result<()> {
/// # use serde_arrow::schema::{SerdeArrowSchema, TracingOptions};
/// # use serde_arrow::schema::{SerdeArrowSchema, SchemaLike, TracingOptions};
/// # let samples: Vec<u32> = vec![1, 2, 3, /* ... */ ];
/// # let fields = SerdeArrowSchema::from_samples(&Items(&samples), TracingOptions::default())?
/// # .to_arrow_fields()?;
Expand Down
Loading

0 comments on commit 91973de

Please sign in to comment.