csv_codegen
A Rust procedural macro for generating code from CSV data at compile time. Transform CSV files into Rust constants, functions, structs, and other code using a flexible templating syntax.
Features
- Compile-time CSV processing - CSV files are read and processed during compilation
- Template-based code generation - Use a simple template syntax to generate any Rust code
- Field transformations - Convert CSV data to valid Rust identifiers, constants, types, and literals
- Filtering support - Include/exclude rows based on conditions
- Pivoting - Transform columns into key-value pairs for more flexible data structures
- Type-safe literals - Generate properly typed numeric literals (
42_f64
,10_u32
, etc.)
Installation
Add this to your Cargo.toml
:
[]
= "0.1"
Quick Start
Given a CSV file products.csv
:
name,price,category
apple,1.20,fruit
carrot,0.80,vegetable
banana,0.90,fruit
Generate constants:
use csv_template;
csv_template!;
// Generates:
// pub const APPLE_PRICE: f64 = 1.20_f64;
// pub const CARROT_PRICE: f64 = 0.80_f64;
// pub const BANANA_PRICE: f64 = 0.90_f64;
assert_eq!;
Syntax
csv_template!
Arguments
- CSV path: Relative path to the CSV file from the crate root
- pivot() (optional): Transforms specified columns into key-value pairs
- #for(): Iterates over CSV rows, with optional filtering condition
Field Substitution
Identifier Transformations
#ident(expression)
- Converts to snake_case identifier#CONST(expression)
- Converts to SCREAMING_SNAKE_CASE constant#Type(expression)
- Converts to PascalCase type name
// "Green Apple" becomes:
#ident // green_apple
#CONST // GREEN_APPLE
#Type // GreenApple
Literal Formatting
#({field}_suffix)
- Creates typed literals#("{field}")
- Creates string literals
# // 1.20_f64
# // 42_u32
# // "apple"
Filtering
Filter rows using conditions in #for()
:
csv_template!;
// Only generates functions for fruits:
// pub fn get_apple_price() -> f64 { 1.20_f64 }
// pub fn get_banana_price() -> f64 { 0.90_f64 }
Supported operators:
==
- equality!=
- inequality
Pivoting
Transform columns into key-value pairs:
// sales.csv: product,q1_sales,q2_sales,q3_sales,q4_sales
// widget,100,150,120,200
csv_template!;
This transforms each row into multiple rows with quarter/amount pairs.
Examples
Generate Match Arms
csv_template!;
Generate Structs with Constants
csv_template! );
Pivoting Example
csv_template!
);
// Usage:
assert_eq!;
assert_eq!;
Use Cases
- Configuration from CSV - Generate constants and enums from configuration data
- Test data - Create test fixtures from CSV files
- Code tables - Transform lookup tables into efficient match statements
- Translations - Create internationalization constants from CSV files
Limitations
- CSV files are read at compile time - changes require recompilation
- Field names must be valid when converted to Rust identifiers
- Empty cells are treated as empty strings
- Only basic filtering conditions are supported (
==
,!=
)
License
Licensed under Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)