typed-arrow provides a strongly typed, fully compile-time way to declare Arrow schemas in Rust. It maps Rust types directly to arrow-rs typed builders/arrays and arrow_schema::DataType — without any runtime DataType switching — enabling zero runtime cost, monomorphized column construction and ergonomic ORM-like APIs.
Why compile-time Arrow?
Performance: monomorphized builders/arrays with zero dynamic dispatch; avoids runtime DataType matching.
matching. Safety: column types, names, and nullability live in the type system; mismatches fail at compile time.
Interop: uses arrow-array / arrow-schema types directly; no bespoke runtime layer to learn.
Quick Start
use typed_arrow :: { prelude :: * , schema :: SchemaMeta } ; use typed_arrow :: { Dictionary , TimestampTz , Millisecond , Utc , List } ; # [ derive ( typed_arrow :: Record ) ] struct Address { city : String , zip : Option < i32 > } # [ derive ( typed_arrow :: Record ) ] struct Person { id : i64 , # [ record ( nested ) ] address : Option < Address > , tags : Option < List < Option < i32 > > > , // List column with nullable items code : Option < Dictionary < i32 , String > > , // Dictionary
joined : TimestampTz < Millisecond , Utc > , // Timestamp(ms) with timezone (UTC) } fn main ( ) { // Build from owned rows let rows = vec ! [ Person { id : 1 , address : Some ( Address { city : "NYC" . into ( ) , zip : None } ) , tags : Some ( List ( vec! [ Some ( 1 ) , None , Some ( 3 ) ] ) ) , code : Some ( Dictionary ( "gold" . into ( ) , std :: marker :: PhantomData ) ) , joined : TimestampTz :: < Millisecond , Utc > ( 1_700_000_000_000 , std :: marker :: PhantomData , ) , } , Person { id : 2 , address : None , tags : None , code : None , joined : TimestampTz :: < Millisecond , Utc > ( 1_700_000_100_000 , std :: marker :: PhantomData , ) , } , ] ; let mut b = < Person as BuildRows > :: new_builders ( rows . len ( ) ) ; b . append_rows ( rows ) ; let arrays = b . finish ( ) ; // Compile-time schema + RecordBatch let batch = arrays . into_record_batch ( ) ; assert_eq ! ( batch . schema ( ) . fields ( ) . len ( ) , < Person as Record > :: LEN ) ; println ! ( "rows={}, field0={}" , batch . num_rows ( ) , batch . schema ( ) . field ( 0 ) . name ( ) ) ; }
Add to your Cargo.toml (derives enabled by default):
[ dependencies ] typed-arrow = { version = " 0.x " }
When working in this repository/workspace:
[ dependencies ] typed-arrow = { path = " . " }
Examples
Run the included examples to see end-to-end usage:
01_primitives — derive Record , inspect DataType , build primitives
— derive , inspect , build primitives 02_lists — List and List