Four coercion levels, one API
| Level | What it does | Use when |
|---|---|---|
| Exact | No type conversion at all | Production validation |
| SafeWidening | int→float, bool→int (lossless only) | Conservative pipelines |
| StringCoercion | "42"→42, "true"→true, null sentinels | CSV/config/env data |
| BestEffort | Everything above + JSON stringify, array unwrap | Exploratory/prototyping |
Every coercion produces a diagnostic — what happened, the risk level, and a suggestion for tightening.
16+ data types from raw strings
guess_type() identifies types with confidence scores. Multiple types can match — the full ranked list is returned.
| Category | Types detected |
|---|---|
| Primitives | Integer, Float, Boolean, NullSentinel |
| Dates | ISO 8601, US/EU dates, Unix timestamps, HL7, compact, week dates |
| Finance | Currency (19 symbols), Credit Card (Luhn), IBAN (MOD-97) |
| Identity | UUID, Email, Phone, SSN, EIN, NHS, NPI, EU VAT, ISBN |
| Structure | JSON, URL, IP Address, Unit Value |
Built-in parsers for real-world data
Dates
15+ format detection and conversion: ISO 8601, US/EU slash dates, dot-separated European, dash-separated, HL7 v2, Unix seconds/millis, abbreviated months, GEDCOM, year-only, ISO week dates.
Currencies
19 symbols (including A$, C$, HK$, €, £, ¥), 28 currency codes, locale detection (US dot-decimal vs European comma-decimal), accounting negative format.
Medical
30+ analyte conversion (glucose, cholesterol, HbA1c, creatinine, etc.), reference range classification, eGFR calculation, BMI, corrected calcium, FHIR observation parsing, HL7 datetime, pharma abbreviations.
Identifiers
12 types with format validation and checksums: IBAN (MOD-97), Credit Card (Luhn + BIN detection for Visa/MC/Amex/Discover/JCB/Diners/Maestro), ISBN-10/13, US SSN, US EIN, UK NHS (MOD-11), US NPI (Luhn), EU VAT (country-specific), UUID, Email, Phone.
Units
Weight, length, volume, temperature, data, time. Qualified weight (gross/net/tare), pack notation (6x500ml, case of 12), UN/ECE code recognition, unit conversion.
Coordinates
Decimal degrees, DMS (degrees/minutes/seconds), ISO 6709. Latitude/longitude validation, order detection.
Anthropic, OpenAI, Ollama — one struct
Parse responses from any provider into a unified NormalizedResponse:
// Same struct regardless of provider
let text = response.text();
let tools = response.tool_uses();
let usage = response.usage; // input_tokens, output_tokens, cache tokens
Round-trip: parse → emit → re-parse preserves all data. SSE streaming parser included.
Struct shaping with compile-time safety
#[derive(Laminate)]
struct Config {
#[laminate(coerce)] // auto-convert string→number
port: u16,
#[laminate(coerce, default)] // missing → false, "yes" → true
debug: bool,
#[laminate(rename = "apiKey")]
api_key: String,
#[laminate(overflow)] // unknown fields → HashMap
extra: HashMap<String, Value>,
}
Three shaping modes
shape_lenient()
Coerce and continue, diagnostics available
shape_absorbing()
Capture unknown fields in overflow
shape_strict()
Reject any coercion or unknown fields
Infer structure from data, then audit against it
- Per-field type detection (dominant type, mixed-type flag)
- Fill rate and null tracking
- Required field inference
- External constraints (override inferred types/nullability)
- Violation reporting (TypeMismatch, MissingRequired, UnknownField)
Context-aware coercion defaults
Tell laminate where the data came from, and it adjusts coercion defaults:
| Hint | Default coercion | Why |
|---|---|---|
| SourceHint::Csv | StringCoercion | CSV columns are always strings |
| SourceHint::Json | Exact | JSON preserves types |
| SourceHint::Env | StringCoercion | Env vars are always strings |