Skip to content

feat(renderer): add optional polymorphic From conversions - #323

Merged
Bergmann89 merged 1 commit into
Bergmann89:masterfrom
sundermann:feat/polymorphic-from
Nov 12, 2026
Merged

Bergmann89 merged 1 commit into
Bergmann89:masterfrom
sundermann:feat/polymorphic-from

Conversation

@sundermann

@sundermann sundermann commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Adds optional From<Concrete> implementations for polymorphic choice enums so callers can construct them with .into(). Select RenderStep::PolymorphicFrom alongside dynamic-to-choice conversion. The step is absent from the default pipeline.

Changes

  • Add an independent PolymorphicFromRenderStep, including traversal of unflattened content enums. Type and serialization renderers need no conversion hooks, and RendererFlags::all() does not enable the feature.
  • Respect generated variant names, module paths, boxing, and allocator configuration. Skip ambiguous payloads using conservative type comparison.
  • Document that external Rust aliases are opaque: a custom Text aliasing String alongside a String payload can cause E0119. Use a newtype or omit the step in that case.
  • Consolidate alias and allocator coverage, remove redundant fixtures and substring assertions, and test standalone composition and explicit opt-in.

Public API addition: config::RenderStep gains PolymorphicFrom; exhaustive matches must handle the new variant. The concrete PolymorphicFromRenderStep is also exported. Default generated output is unchanged.

Checklist

  • Tests for the change (a bug fix has a test that fails without the fix)
  • Changed snapshots are regenerated with update-expectations and reviewed
  • cargo fmt, cargo clippy and cargo test pass (see CONTRIBUTING.md)
  • Breaking changes of the public API or the generated code are described above

@sundermann sundermann changed the title Feat/polymorphic from feat(renderer): add optional polymorphic From conversions Nov 12, 2026

@Bergmann89 Bergmann89 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I like the feature!

I would prefer to implement it as its own render step instead of a renderer flag that is hooked into the four type renderers. The conversions do not depend on anything of these renderers, they only need the ComplexDataEnum. A separate step can match DataTypeVariant::Complex in render_type and walk ComplexData::Enum { type_, content_type } (including the content type for the unflattened case). It is then completely independent of the other steps, users add it with something like RenderStep::PolymorphicFrom to the pipeline, and RendererFlags::POLYMORPHIC_FROM is not needed anymore (which also avoids that RendererFlags::all() enables it).

Please also document in the step docs that payloads which only differ by an external type alias cannot be detected: the comparison uses the final identifiers, so a custom type Text with type Text = String next to a String variant gets two From impls for the same type and fails with E0119. The generator cannot see user aliases, so a note (use a newtype or do not use the step) is enough.

The remaining comments are about the tests.

Comment thread xsd-parser/tests/mod.rs Resolved
@sundermann
sundermann force-pushed the feat/polymorphic-from branch from dfe3186 to 403be06 Compare November 12, 2026 18:28
Add an explicit PolymorphicFromRenderStep and expose it through
RenderStep::PolymorphicFrom. Keep it independent of the type renderers so
RendererFlags::all() does not opt in to conversions.

Walk nested complex content to support flattened and content enums. Use
the generated variant names, payload paths, boxing decisions and allocator
configuration, skipping ambiguous payloads using conservative type keys.
Document that external Rust aliases are opaque and may require a newtype
or omitting the step to avoid conflicting From implementations.

Cover explicit opt-in, independent step composition, allocator-aware
boxing, aliases, recursive and nullable payloads, concrete bases, module
layouts and Serde renderers. Keep fixtures focused on conversions and
reuse alias and allocator coverage instead of duplicating snapshots.
@sundermann
sundermann force-pushed the feat/polymorphic-from branch from 403be06 to 6bc42eb Compare November 12, 2026 18:40
@sundermann

Copy link
Copy Markdown
Contributor Author

Thanks for the review, updated the PR and the implementation is cleaner now.

@Bergmann89
Bergmann89 merged commit c124cd9 into Bergmann89:master Nov 12, 2026
2 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.

2 participants