Problem
Every nvisy_postgres DB enum repeats each variant's string value across three attributes:
/// Workspace settings or metadata were updated
#[db_rename = "workspace.updated"]
#[serde(rename = "workspace.updated")]
#[strum(serialize = "workspace.updated")]
WorkspaceUpdated,
- The string is duplicated 3× per variant. A typo in one silently diverges the DB value from the wire value — a real correctness hazard, not just verbosity.
- ~19 enums under
crates/nvisy-postgres/src/types/enums/ follow this pattern; the largest (activity_type, 32 variants; webhook_event, 24) are mostly this boilerplate (152 lines for 24 variants).
Proposed direction
Collapse the three renames into one value, while keeping the enum, its derives, per-variant doc comments, and hand-written impl blocks exactly as they are (readability + rustdoc + grep intact):
/// Workspace settings or metadata were updated
#[db_str = "workspace.updated"] // expands to db_rename + serde(rename) + strum(serialize)
WorkspaceUpdated,
This enforces the three stay in sync by construction.
Design notes / caveats (from investigation)
- A full
postgres_enum! generator that owns the enum is NOT recommended. The enums aren't uniform: they differ in derives (IntoStaticStr on some), #[default] variants, Hash, the schema cfg_attr, section comments, and each has custom impls (category(), DOCUMENTS, as_subject()). A generator would either drop that expressiveness or become as noisy as what it replaces.
- Container-level
#[serde(rename_all)] + #[strum(serialize_all)] won't work for the dotted event enums (WorkspaceUpdated → workspace.updated is not a mechanical case transform). It could work for the simple lowercase enums (Original → original) but that's a minority and mixing approaches adds inconsistency.
file_kind currently omits strum(serialize) (its strum Display is the variant name, not the db value) — so the enums aren't even consistent about which three attributes apply. The macro must not silently change that enum's Display output.
- A per-variant attribute macro requires a proc-macro crate (attribute macros can't be
macro_rules!) — a new workspace crate + syn/quote. That's the main cost to weigh. Alternative: a macro_rules! that generates the enum but only handles the common case, leaving irregular enums hand-written (no new crate, less flexible).
Decision needed
Proc-macro attribute (cleanest, new crate) vs. macro_rules! generator (no new crate, less flexible). Behavior must be identical for every existing enum — verify file_kind's Display and all DB round-trips are unchanged.
Problem
Every
nvisy_postgresDB enum repeats each variant's string value across three attributes:crates/nvisy-postgres/src/types/enums/follow this pattern; the largest (activity_type, 32 variants;webhook_event, 24) are mostly this boilerplate (152 lines for 24 variants).Proposed direction
Collapse the three renames into one value, while keeping the enum, its derives, per-variant doc comments, and hand-written
implblocks exactly as they are (readability + rustdoc + grep intact):This enforces the three stay in sync by construction.
Design notes / caveats (from investigation)
postgres_enum!generator that owns the enum is NOT recommended. The enums aren't uniform: they differ in derives (IntoStaticStron some),#[default]variants,Hash, theschemacfg_attr, section comments, and each has customimpls (category(),DOCUMENTS,as_subject()). A generator would either drop that expressiveness or become as noisy as what it replaces.#[serde(rename_all)]+#[strum(serialize_all)]won't work for the dotted event enums (WorkspaceUpdated→workspace.updatedis not a mechanical case transform). It could work for the simple lowercase enums (Original→original) but that's a minority and mixing approaches adds inconsistency.file_kindcurrently omitsstrum(serialize)(its strum Display is the variant name, not the db value) — so the enums aren't even consistent about which three attributes apply. The macro must not silently change that enum's Display output.macro_rules!) — a new workspace crate +syn/quote. That's the main cost to weigh. Alternative: amacro_rules!that generates the enum but only handles the common case, leaving irregular enums hand-written (no new crate, less flexible).Decision needed
Proc-macro attribute (cleanest, new crate) vs.
macro_rules!generator (no new crate, less flexible). Behavior must be identical for every existing enum — verifyfile_kind's Display and all DB round-trips are unchanged.