Tech News
← Back to articles

Show HN: Typed-arrow – compile‑time Arrow schemas for Rust

read original related products more articles

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:

... continue reading