Skip to content

Commit 54442bd

Browse files
committed
feat: support generic Record derivation
1 parent 19b9072 commit 54442bd

4 files changed

Lines changed: 412 additions & 78 deletions

File tree

examples/14_generic_record.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use typed_arrow::prelude::*;
2+
3+
#[derive(Record)]
4+
struct C<T> {
5+
data: T,
6+
}
7+
8+
#[derive(Record)]
9+
struct S<T> {
10+
d: u32,
11+
c: C<T>,
12+
}
13+
14+
fn main() {
15+
let rows = vec![
16+
S {
17+
d: 1,
18+
c: C {
19+
data: "a".to_string(),
20+
},
21+
},
22+
S {
23+
d: 2,
24+
c: C {
25+
data: "b".to_string(),
26+
},
27+
},
28+
];
29+
30+
let mut b = <S<String> as BuildRows>::new_builders(rows.len());
31+
b.append_rows(rows);
32+
let batch = b.finish().into_record_batch();
33+
let _ = batch;
34+
}

tests/generic_record.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use arrow_array::{Array, StringArray, StructArray};
2+
use arrow_schema::DataType;
3+
use typed_arrow::{prelude::*, schema::SchemaMeta};
4+
5+
#[derive(Record)]
6+
struct C<T> {
7+
data: T,
8+
}
9+
10+
#[derive(Record)]
11+
struct S<T> {
12+
d: u32,
13+
c: C<T>,
14+
}
15+
16+
#[test]
17+
fn generic_schema_and_rows_u32() {
18+
let fields = <C<u32> as SchemaMeta>::fields();
19+
assert_eq!(fields.len(), 1);
20+
assert_eq!(fields[0].data_type(), &DataType::UInt32);
21+
22+
let rows = vec![C { data: 1u32 }, C { data: 2u32 }];
23+
let mut b = <C<u32> as BuildRows>::new_builders(rows.len());
24+
b.append_rows(rows);
25+
let arrays = b.finish();
26+
27+
assert_eq!(arrays.data.len(), 2);
28+
assert_eq!(arrays.data.value(0), 1);
29+
assert_eq!(arrays.data.value(1), 2);
30+
}
31+
32+
#[test]
33+
fn generic_nested_struct_string() {
34+
let fields = <S<String> as SchemaMeta>::fields();
35+
assert_eq!(fields.len(), 2);
36+
assert_eq!(fields[0].data_type(), &DataType::UInt32);
37+
match fields[1].data_type() {
38+
DataType::Struct(children) => {
39+
assert_eq!(children.len(), 1);
40+
assert_eq!(children[0].name(), "data");
41+
assert_eq!(children[0].data_type(), &DataType::Utf8);
42+
}
43+
other => panic!("expected Struct, got {other:?}"),
44+
}
45+
46+
let rows = vec![
47+
S {
48+
d: 1,
49+
c: C {
50+
data: "a".to_string(),
51+
},
52+
},
53+
S {
54+
d: 2,
55+
c: C {
56+
data: "b".to_string(),
57+
},
58+
},
59+
];
60+
let mut b = <S<String> as BuildRows>::new_builders(rows.len());
61+
b.append_rows(rows);
62+
let arrays = b.finish();
63+
64+
assert_eq!(arrays.d.len(), 2);
65+
assert_eq!(arrays.d.value(1), 2);
66+
67+
let c: StructArray = arrays.c;
68+
assert_eq!(c.len(), 2);
69+
let data = c
70+
.column(0)
71+
.as_any()
72+
.downcast_ref::<StringArray>()
73+
.expect("data column is StringArray");
74+
assert_eq!(data.value(0), "a");
75+
assert_eq!(data.value(1), "b");
76+
}
77+
78+
#[cfg(feature = "views")]
79+
#[test]
80+
fn generic_views_roundtrip() -> Result<(), typed_arrow::error::SchemaError> {
81+
let rows = vec![C { data: 10u32 }, C { data: 20u32 }];
82+
let mut b = <C<u32> as BuildRows>::new_builders(rows.len());
83+
b.append_rows(rows);
84+
let batch = b.finish().into_record_batch();
85+
86+
let values: Vec<u32> = batch
87+
.iter_views::<C<u32>>()?
88+
.try_flatten()?
89+
.into_iter()
90+
.map(|v| v.data)
91+
.collect();
92+
assert_eq!(values, vec![10, 20]);
93+
Ok(())
94+
}

tests/success/generic_record.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use typed_arrow::prelude::*;
2+
3+
#[derive(Record)]
4+
struct C<T> {
5+
data: T,
6+
}
7+
8+
#[derive(Record)]
9+
struct S<T> {
10+
d: u32,
11+
c: C<T>,
12+
}
13+
14+
fn main() {
15+
let _ = C { data: 1u32 };
16+
let _ = S { d: 1, c: C { data: 2u32 } };
17+
}

0 commit comments

Comments
 (0)