Function pluralize
pub fn pluralize(value: &str) -> StringExpand description
English pluralization used for both REST route segments and generated
table/column names — the single implementation cratestack-core and
cratestack-migrate both call (cratestack#504; previously two
hand-synced copies, cratestack-migrate::naming::pluralize mirroring
this one, that had already drifted apart on this exact rule).
Rules, in order: a value ending in s gets es appended (bus ->
buses); a value ending in a consonant + y swaps the y for
ies (category -> categories, webhook_delivery ->
webhook_deliveries); a value ending in a vowel + y (day) or
anything else just gets a bare s appended (day -> days).
Still not a grammatically complete English pluralizer — irregular
plurals (person -> people) are not handled, and there is
deliberately no way to override the result for a given model today.
@@map(...) is the planned escape hatch for that (flagged as a known
gap by cratestack#504, not yet implemented, out of scope here). This
function only needs to match the server’s route registration and the
migration engine’s table naming, not be linguistically ideal.
Migrating past cratestack#504’s y -> ies fix. This function
feeds cratestack-migrate’s table-name derivation
(cratestack_migrate::naming::table_name), and cratestack-migrate’s
diff engine matches tables by name only — it never infers a
rename from two schemas that otherwise look related
(crates/cratestack-migrate/src/diff.rs). Any deployed model whose
name ends in a consonant + y (Category, Delivery, Entry,
Query, …) changes its derived table name on this upgrade
(categorys -> categories). Running cratestack migrate diff
against such a schema without first declaring the rename produces
DropTable(categorys) + CreateTable(categories) — applying that
migration destroys the table’s data.
Before running migrate diff after upgrading past this change, add
@@rename(from = "<old_table_name>") to every affected model (e.g.
@@rename(from = "categorys") on model Category) so the diff
engine emits ALTER TABLE ... RENAME TO ... instead. See
crates/cratestack-migrate/src/convert/renames.rs for the attribute
and crates/cratestack-migrate/src/emit/postgres/tests/renames.rs’s
pluralization_change_with_rename_marker_is_a_rename_not_drop_and_create
test for a worked example of exactly this scenario (and its sibling
..._without_rename_marker_drops_and_recreates, which pins down what
happens if you skip this step).