Skip to content

derive Type on serde from/try_from helpers (specta rc.24 fix)#5

Merged
johncarmack1984 merged 2 commits into
mainfrom
john/specta-rc24-helpers
May 5, 2026
Merged

derive Type on serde from/try_from helpers (specta rc.24 fix)#5
johncarmack1984 merged 2 commits into
mainfrom
john/specta-rc24-helpers

Conversation

@johncarmack1984
Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #3. With specta 2.0.0-rc.24, the workspace's serde-phase validation traverses serde(from = ...) / serde(try_from = ...) helpers and refuses to derive Type unless the helper structs themselves implement Type. This was blocking fltsci/fltsci from depending on this fork with features = ["specta"] enabled.

The fix keeps the helper-based deserialization intact while satisfying specta:

  • Add #[derive(specta::Type)] + #[specta(inline)] to the internal helper types: DeserializeFeatureHelper, DeserializeFeatureCollectionHelper, RawGeometry, GeometryType, FeatureType, FeatureCollectionType. The inline flag means specta knows about them but doesn't emit separate TS exports.
  • Cfg-gate #[serde(expecting = "...")] on Id and RawGeometry under the specta feature -- rc.24's macro parser trips on expecting. The attribute only affects error-message UX, so cfg-gating it preserves runtime behavior when specta is off and skips the trip when specta is on. Two tests that asserted on the cfg-gated error messages get the assertion cfg-gated to match.

Test results

feature config unit integration doctest
default 98 pass 16 pass 37 pass
--features specta 98 pass 16 pass 37 pass

No deserialization regression -- the helper-based round-tripping (with all its existing validation: tag enum check, foreign-members normalization, etc.) still works exactly as before. Specta just sees the helpers exist and is satisfied.

Why this beats the closed #4

#4 dropped the helpers entirely and accepted 18 deserialize-test regressions. That broke geometry round-trip in real ways (foreign_members greedily caught variant fields). This PR keeps the helpers, so deserialization is unchanged, and only adds metadata for specta to consume.

specta-rc.24's serde-phase validation traverses `serde(from = ...)` /
`serde(try_from = ...)` and refuses to derive Type unless the
helper structs themselves implement Type. Adds the derive on the
internal helpers (DeserializeFeatureHelper, DeserializeFeatureCollectionHelper,
RawGeometry, GeometryType, FeatureType, FeatureCollectionType) with
`#[specta(inline)]` so they don't get separately exported in TS bindings.

Cfg-gates `#[serde(expecting = "...")]` on Id and RawGeometry under
the specta feature -- specta-rc.24's macro parser trips on
`expecting`, but it only affects error-message UX so cfg-gating it
preserves runtime behavior when specta is off and skips the trip when
specta is on. Two tests that asserted on the cfg-gated error messages
get the assertion cfg-gated to match.

All 98 unit + 16 integration + 37 doctest pass under both default
features and `--features specta`. No deserialization regression -- the
helper-based round-tripping still works exactly as before; specta
just sees the helpers exist and is satisfied.
@johncarmack1984 johncarmack1984 merged commit 2aa5c3f into main May 5, 2026
4 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.

1 participant