What you'll learn: Lessons from a real-world translation of ~100K lines of C++ to ~90K lines of Rust across ~20 crates. Five key transformation patterns and the architectural decisions behind them.
We translated a large C++ diagnostic system (~100K lines of C++) into a Rust implementation (~20 Rust crates, ~90K lines)
This section shows the actual patterns used β not toy examples, but real production code
The Wrong Approach (literal translation): Put all events in one heterogeneous collection, then downcast β this is what C++ does with vector<unique_ptr<Base>>
The Right Approach: Separate typed Vecs eliminate all downcasting. Each consumer asks for exactly the event type it needs
Performance: Separate Vecs give better cache locality (all degrade events are contiguous in memory)
// C++ topology library: PcieDevice uses enable_shared_from_this // because parent and child nodes both need to reference each otherclassPcieDevice : public std::enable_shared_from_this<PcieDevice> {
public:
std::shared_ptr<PcieDevice> m_upstream;
std::vector<std::shared_ptr<PcieDevice>> m_downstream;
// ... device datavoidAddChild(std::shared_ptr<PcieDevice> child){
child->m_upstream = shared_from_this(); // Parent β child cycle!
m_downstream.push_back(child);
}
};
// Problem: parentβchild and childβparent create reference cycles// Need weak_ptr to break cycles, but easy to forget
// Example: components.rs β Flat Vec owns all devicespubstructPcieDevice {
pub base: PcieDeviceBase,
pub kind: PcieDeviceKind,
// Tree linkage via indices β no reference counting, no cyclespub upstream_idx: Option<usize>, // Index into the arena Vecpub downstream_idxs: Vec<usize>, // Indices into the arena Vec
}
// The "arena" is simply a Vec<PcieDevice> owned by the tree:pubstructDeviceTree {
devices: Vec<PcieDevice>, // Flat ownership β one Vec owns everything
}
implDeviceTree {
pubfnparent(&self, device_idx: usize) ->Option<&PcieDevice> {
self.devices[device_idx].upstream_idx
.map(|idx| &self.devices[idx])
}
pubfnchildren(&self, device_idx: usize) ->Vec<&PcieDevice> {
self.devices[device_idx].downstream_idxs
.iter()
.map(|&idx| &self.devices[idx])
.collect()
}
}