ironrdp-pdu is the largest Core-tier crate by API surface and carries _TODO_: clean up the dependencies in ARCHITECTURE.md. The dependency-cleanup TODO is fundamentally a crate-boundary problem: today the crate has the union of dependencies for every PDU type, and no way to express "I only need the RFX PDUs."
A spec-aligned split:
ironrdp-pdu-bcgr: MS-RDPBCGR core (residual base)
ironrdp-pdu-egdi: MS-RDPEGDI drawing orders
ironrdp-pdu-rfx: MS-RDPRFX codec PDUs
- … more as needed
Proposed naming: ironrdp-pdu-* infix (stable namespace marker, avoids rdp doubling, matches tokio-util/tower-http). Open to alternatives: settle this before the first extraction; renaming after the fact is worse than the original split.
Already-extracted spec families (do not redo)
These are not in ironrdp-pdu today and are out of scope for this issue:
- MS-RDPEGFX PDUs → ironrdp-egfx::pdu (cmd.rs, avc.rs)
- MS-RDPECLIP PDUs → ironrdp-cliprdr / ironrdp-cliprdr-format
- MS-RDPEFS PDUs → ironrdp-rdpdr (co-located with the channel implementation)
- MS-RDPEDISP PDUs → ironrdp-displaycontrol (co-located with the channel implementation)
Channel-internal PDUs: pattern decision
Some channel crates (ironrdp-rdpdr, ironrdp-displaycontrol) self-contain their PDUs alongside the state machine. Two patterns are possible:
- Pattern A: Channel self-contains PDUs. One crate per spec; PDU types and state machine evolve together; lower crate count; no external PDU consumption story.
- Pattern B: PDUs in a dedicated
ironrdp-pdu-* crate, channel depends on it. Reusable wire types (tools, proxies, fuzz harnesses, alternative impls); no_std-friendly PDU layer; consistent with the codec-split rationale and with this issue's premise; more crates and more public API surface to design.
Default: Pattern A, unless someone asks for Pattern B for a specific channel.
Rationale: lower maintenance overhead, and the dependency entanglement is already low. We've split system integration out into *-native crates (ironrdp-rdpdr-native, ironrdp-rdpsnd-native, ironrdp-cliprdr-native), so the channel state-machine crates themselves are already lightweight; the marginal compile cost a downstream consumer pays to get the PDUs alongside the state machine is small. Pattern B's main argument (PDU layer compiles ahead of heavy deps) doesn't carry much weight here.
Both patterns remain legitimate; the deciding factor is whether there's a real consumer for the PDUs without the channel.
Why blocked by #1349
Codec crates need codec PDU types. Splitting PDUs first churns import surface across all consumers; codec-first lets the PDU split be informed by real dependency edges. We also want the per-crate template stabilized before applying it to the larger PDU surface.
Sequencing within this issue
- Settle naming convention.
- Confirm
ironrdp-pdu stays as residual base (Rectangles, etc).
- Extract easiest spec family first. Not RDPBCGR: too central, too entangled.
Acceptance
ironrdp-pduis the largest Core-tier crate by API surface and carries_TODO_: clean up the dependenciesinARCHITECTURE.md. The dependency-cleanup TODO is fundamentally a crate-boundary problem: today the crate has the union of dependencies for every PDU type, and no way to express "I only need the RFX PDUs."A spec-aligned split:
ironrdp-pdu-bcgr: MS-RDPBCGR core (residual base)ironrdp-pdu-egdi: MS-RDPEGDI drawing ordersironrdp-pdu-rfx: MS-RDPRFX codec PDUsProposed naming:
ironrdp-pdu-*infix (stable namespace marker, avoidsrdpdoubling, matchestokio-util/tower-http). Open to alternatives: settle this before the first extraction; renaming after the fact is worse than the original split.Already-extracted spec families (do not redo)
These are not in ironrdp-pdu today and are out of scope for this issue:
Channel-internal PDUs: pattern decision
Some channel crates (
ironrdp-rdpdr,ironrdp-displaycontrol) self-contain their PDUs alongside the state machine. Two patterns are possible:ironrdp-pdu-*crate, channel depends on it. Reusable wire types (tools, proxies, fuzz harnesses, alternative impls);no_std-friendly PDU layer; consistent with the codec-split rationale and with this issue's premise; more crates and more public API surface to design.Default: Pattern A, unless someone asks for Pattern B for a specific channel.
Rationale: lower maintenance overhead, and the dependency entanglement is already low. We've split system integration out into
*-nativecrates (ironrdp-rdpdr-native,ironrdp-rdpsnd-native,ironrdp-cliprdr-native), so the channel state-machine crates themselves are already lightweight; the marginal compile cost a downstream consumer pays to get the PDUs alongside the state machine is small. Pattern B's main argument (PDU layer compiles ahead of heavy deps) doesn't carry much weight here.Both patterns remain legitimate; the deciding factor is whether there's a real consumer for the PDUs without the channel.
Why blocked by #1349
Codec crates need codec PDU types. Splitting PDUs first churns import surface across all consumers; codec-first lets the PDU split be informed by real dependency edges. We also want the per-crate template stabilized before applying it to the larger PDU surface.
Sequencing within this issue
ironrdp-pdustays as residual base (Rectangles, etc).Acceptance
ironrdp-pduscope reduced.