Commit 2d5acfb
feat(gts-macros): implement GtsSchema derive macro with gts(...) struct/field attributes
Replaces the prior plan for a future attribute-macro rewrite with a shipped
derive macro. `#[derive(GtsSchema)]` + `#[gts(...)]` helper attributes live
alongside the existing `#[struct_to_gts_schema]` attribute macro; coexistence
is the steady state, deprecation and removal are out of scope.
Highlights:
- Struct-level `#[gts(dir_path, schema_id, description, extends)]` and
field-level `#[gts(type_field | instance_id | skip)]` attribute grammar.
- Identity-field rule enforced at compile time: every root struct declares
exactly one of `type_field` / `instance_id`; derived structs (`extends =
Parent`) declare neither. `extends = None` is an equivalent explicit root
marker.
- Generated `pub fn new(...)` constructor on every named-field struct.
`type_field` auto-populated from `GtsSchemaId::new(<P as GtsSchema>::SCHEMA_ID)`
(generic root) or `Self::gts_schema_id().clone()` (non-generic root);
`instance_id` passed by the caller.
- Unconditional block on direct `Serialize` / `Deserialize` on derived
structs via the `GtsNoDirectSerialize` / `GtsNoDirectDeserialize` marker
traits. No opt-out attribute.
- Spec-correct `"x-gts-ref": "/$id"` on identity fields; generic
`"x-gts-ref": "gts.*"` retained for other `GtsSchemaId` fields.
- `description` now emitted into runtime schemas via
`gts_schema_with_refs()`.
- Per-field serde rename in the nested deserializer (replaces the prior
`rename_all = "snake_case"` blanket).
Docs:
- New ADR (`docs/001-gts-schema-derive-macro-adr.md`).
- Migration guide (`docs/002-struct-to-gts-schema-migration.md`) describing
the old/new diff, schema-output parity, compile-fail fixture mapping, and
the coexistence stance.
- Implementation plan (`docs/002-macro-migration-implementation-plan.md`).
- Old `001-macro-proposal.md` / `001-macro-alignment-*.md` superseded and
removed.
- `gts-macros/README.md` rewritten around the derive macro, with the old
macro presented as legacy.
Tests (all suites green, ~104 tests + 24 trybuild fixtures):
- `v2_compile_fail/` — compile-time rejection of invalid configurations
(missing identity, wrong field types, schema-ID format, inheritance
mismatches, direct-serde on nested, etc.).
- `v2_integration_tests` — runtime API + schema output for base structs,
incl. generated-constructor behavior.
- `v2_inheritance_tests` — multi-level inheritance chains.
- `v2_serialization_tests` — `Serialize` / `Deserialize` round-trips through
the `GtsSerialize` bridge.
- `v2_serde_rename_tests` — per-field `#[serde(rename)]` handling.
- `v2_parity_tests` — identical output vs `#[struct_to_gts_schema]` on
equivalent structs (with the `x-gts-ref: "/$id"` improvement noted
above).
- `v2_inheritance_tests_mixed` — interop between old and new macros.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Andre Smith <andre.smith@acronis.com>1 parent 5376ad5 commit 2d5acfb
71 files changed
Lines changed: 5619 additions & 2535 deletions
File tree
- docs
- gts-macros
- src
- tests
- compile_fail
- v2_compile_fail
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
This file was deleted.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
0 commit comments