Skip to content

Prohibit direct serialization of nested GTS structs (incl. cfg_attr)#50

Merged
Artifizer merged 1 commit intoGlobalTypeSystem:mainfrom
KvizadSaderah:feature/24-prohibit-direct-nested-serialization
Feb 12, 2026
Merged

Prohibit direct serialization of nested GTS structs (incl. cfg_attr)#50
Artifizer merged 1 commit intoGlobalTypeSystem:mainfrom
KvizadSaderah:feature/24-prohibit-direct-nested-serialization

Conversation

@KvizadSaderah
Copy link
Copy Markdown
Collaborator

@KvizadSaderah KvizadSaderah commented Feb 4, 2026

Summary

  • Block direct Serialize/Deserialize on nested GTS structs via marker traits and macro-emitted impls
  • Detect cfg_attr(derive(Serialize/Deserialize)) and add compile-fail coverage
  • Update macro attribute parsing and documentation around derives

Fixes #24

Testing

  • cargo test -p gts-macros
  • cargo test -p gts
  • cargo clippy --all-targets -- -D warnings

…obalTypeSystem#24)

- Block direct Serialize/Deserialize on nested GTS structs via marker traits
- Detect cfg_attr(derive(Serialize/Deserialize)) at compile time
- Add compile-fail tests for coverage

Fixes GlobalTypeSystem#24
@KvizadSaderah KvizadSaderah force-pushed the feature/24-prohibit-direct-nested-serialization branch from 92474d6 to c001a35 Compare February 5, 2026 13:14
@KvizadSaderah
Copy link
Copy Markdown
Collaborator Author

@Artifizer please review

@Artifizer
Copy link
Copy Markdown
Contributor

@KvizadSaderah , please check with @yoskini if it's a duplication of his PR or not

@KvizadSaderah
Copy link
Copy Markdown
Collaborator Author

KvizadSaderah commented Feb 12, 2026

@KvizadSaderah , please check with @yoskini if it's a duplication of his PR or not

already did with LLM, valid for 10.02.2026

⏺ Issue #24: PR #48 vs PR #50 Analysis

  Issue Requirement

  From https://github.com/GlobalTypeSystem/gts-rust/issues/24: direct serialization of nested GTS structs must be prohibited at compile-time. That is, serde_json::to_value(&nested_struct) must produce a compiler error.

  ---
  PR #48 (yoskini) — Soft Prevention

  Strategy: Nested structs still derive Serialize/Deserialize. "Prevention" is achieved by:
  1. Removing gts_instance_json*() convenience methods from nested types
  2. New GtsNestedType trait as a marker
  3. Documentation and compile-fail test only for the missing gts_instance_json() method

  Problem: serde_json::to_value(&nested) still compiles and works. This does NOT fulfill Issue #24's requirement.

  ---
  PR #50 (KvizadSaderah) — Hard Compile-Time Prohibition

  Strategy: Nested structs do NOT get Serialize/Deserialize. Instead:
  1. Macro adds only JsonSchema to nested types, no Serialize/Deserialize
  2. New GtsSerialize/GtsDeserialize traits + blanket impls for standard serde types
  3. Marker traits GtsNoDirectSerialize/GtsNoDirectDeserialize + blanket impl<T: Serialize> GtsNoDirectSerialize for T {} — if someone manually adds #[derive(Serialize)], they get conflicting impls
  4. Detection of cfg_attr(derive(Serialize)) with an explicit compile error
  5. For base structs: #[serde(serialize_with, deserialize_with)] on generic fields for transparent operation via GtsSerialize
  6. Full custom Serialize/Deserialize generation for nested structs (field-by-field)
  7. Two compile-fail tests: direct serialization AND cfg_attr attempt

  ---
  Comparison Table
  ┌────────────────────────────────────────────────┬────────────────────────────┬─────────────────────────────────────┐
  │                    Criteria                    │           PR #48           │               PR #50                │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ serde_json::to_value(&nested) — compile error  │ No                         │ Yes                                 │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ Manual #[derive(Serialize)] on nested — caught │ No                         │ Yes (conflicting impls)             │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ cfg_attr(derive(Serialize)) — caught           │ No                         │ Yes (explicit error)                │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ Compile-fail tests                             │ 1 (only gts_instance_json) │ 2 (direct serialization + cfg_attr) │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ README updated                                 │ No                         │ Yes                                 │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ Implementation complexity                      │ Simpler (~411 ins)         │ More complex (~846 ins)             │
  ├────────────────────────────────────────────────┼────────────────────────────┼─────────────────────────────────────┤
  │ Satisfies Issue #24                            │ Partially                  │ Fully                               │
  └────────────────────────────────────────────────┴────────────────────────────┴─────────────────────────────────────┘
  ---
  Verdict

  The PRs conflict — they solve the same problem with diametrically opposite approaches and touch the same files (gts-macros/src/lib.rs, gts/src/schema.rs, gts/src/lib.rs).

  PR #50 (KvizadSaderah) is clearly the better choice because it is the only one that actually fulfills Issue #24's requirement — compile-time prohibition of direct serialization. PR #48 only removes convenience methods but does not block serde_json::to_value(), which
  leaves a gap in the contract.

@Artifizer Artifizer merged commit ee8d9e6 into GlobalTypeSystem:main Feb 12, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Direct serialization of nested GTS struct must be prohibited compile-time

2 participants