Expand description
The Schema Contract System (Phase 14 — Commit 1, types only).
Single-source-of-truth metadata describing a model’s columns, their Rust types, their expected SQL DDL, and the admin/search flags that flow to the rest of the framework.
§The five type rules
These are the non-negotiable defaults. The validator enforces
them at runtime; the macro layer enforces them at compile time.
Both layers consult RustType::is_compatible_with to decide what
“matches” means.
- IDs —
i64↔BIGINT/BIGSERIAL. Neveri32. - Timestamps —
DateTime<Utc>↔TIMESTAMPTZ. NeverNaiveDateTime. - Money —
Decimal(preferred) ori64cents ↔NUMERIC. Neverf64. TheRustType::F64variant exists for non-money decimals (percentages, scientific data) and is deliberately not compatible withnumeric. - JSON —
serde_json::Value↔JSONB. NeverJSON. - Strings —
String↔TEXT(default).VARCHAR(n)only when strictly required (and matchesStringtoo).
See docs/types.md for the full mapping table. This module’s job
is only to encode the rules; enforcement is the validator and
macro’s job in later commits.
§Stability contract
Adding new variants to RustType is a non-breaking minor-version
addition (the enum is #[non_exhaustive]). Removing or renaming
a variant is breaking. Adding fields to ModelColumn /
ModelSchema / SchemaFlags is non-breaking when the field has
a Default (the structs are #[non_exhaustive]); removing or
retyping a field is breaking.
§Phase scope
Commit 1 ships only the types and the compatibility helpers. The
macro that generates a ModelSchema from a struct
(#[derive(RustioModel)]) ships in commit 2; the runtime validator
that introspects PostgreSQL and compares against ModelSchema
ships in commit 3. Nothing in admin/, search/, migrations/,
or examples/ references this module yet.
Structs§
- Model
Column - One column in a model’s contract.
- Model
Schema - The full schema contract for one model.
- Schema
Flags - Per-column flags consumed by the admin UI and the search indexer.
Enums§
- Rust
Type - The Rust types the contract system knows about. One variant per
scalar shape; nullability is represented separately via
ModelColumn::nullableto avoid doubling the variant count.