Skip to content

Support #[serde(transparent)] structs by generating type aliases - #296

Open
xiao115255 wants to merge 1 commit into
1Password:mainfrom
xiao115255:claude/issue-26
Open

xiao115255 wants to merge 1 commit into
1Password:mainfrom
xiao115255:claude/issue-26

Conversation

@xiao115255

Copy link
Copy Markdown

What & Why

A struct annotated with #[serde(transparent)] serializes as the value of its single non-skipped field, but typeshare still generated a wrapper struct for it. The generated definitions therefore did not match the actual serialized shape (per the examples in #26):

#[typeshare]
#[serde(transparent)]
pub struct Players {
    players: Vec<Player>,
}

Before:

export interface Players {
    players: Player[];
}

After:

export type Players = Player[];

Changes:

  • core/src/parser.rs: when parsing a named struct with #[serde(transparent)] and exactly one non-skipped field, emit a RustItem::Alias to that field's type instead of a wrapper struct. This reuses the existing alias path already taken by single-field tuple structs, so all language backends get the correct behavior. Structs whose transparent field is overridden via #[typeshare(serialized_as)] are handled as well; structs that do not have exactly one non-skipped field fall back to the previous behavior (serde itself rejects those at compile time).
  • core/data/tests/can_handle_serde_transparent/: new snapshot test covering both a single-field transparent struct and a transparent struct with an additional #[serde(skip)] field, across kotlin, swift, typescript, scala, go, and python.
  • docs/src/usage/annotations.md: document the supported annotation.

Fixes #26

How Tested

  • TDD: added the snapshot test first and confirmed it failed against the pre-change parser, then implemented the fix.
  • cargo test --workspace: all 315 snapshot tests plus unit/doc tests pass (full suite, not just the new tests) — no regressions.
  • cargo fmt --all -- --check: clean.
  • cargo clippy --workspace --all-targets: no new warnings (37 pre-existing before and after).
  • End-to-end: ran the CLI on the issue's exact scenario (cargo run -p typeshare-cli -- --lang=typescript --output-file=out.ts sample.rs) and confirmed it now emits export type Players = Player[];.

AI Disclosure

This PR was prepared with AI assistance (Claude Code), reviewed and submitted by @xiao115255.

A struct annotated with #[serde(transparent)] serializes as the value of
its single non-skipped field, but typeshare still generated a wrapper
struct for it, producing definitions that do not round-trip with the
serialized data.

Parse such structs as a type alias to the non-skipped field's type,
mirroring what serde actually produces. This reuses the existing alias
path taken by single-field tuple structs.

Fixes 1Password#26

Co-Authored-By: Claude Code <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

Transparent container attribute has no effect on structs

1 participant